Comments (69)
We have no expectation of ever doing anything like this.
from roslyn.
Just noticed this in Don Syme’s History of F# paper for HOPL 😁
from roslyn.
This proposal seems related to object expressions in F# or anonymous inner classes in Java, both of which let you specify class implementations right when you new the objects up.
You could certainly imagine an evolution of anonymous objects in C# that would combine the current behavior with the ability to inherit classes, implement interfaces and supply member implementations.
from roslyn.
That's disappointing.
Here's an example that came up today. Let's say we have some interface IParseMessages
:
interface IParseMessages
{
bool Parse(IMessage message);
}
Now we want to be able to add other stages to the parsing pipeline (think something like the handlers in ASP.NET), which can decide whether or not to invoke the "base" message parser. None of these handlers know anything about each other (we can't just link them all together when we write them). We could have a type like this:
public interface IMessageHandler
{
bool Parse(IMessage message, Func<IMessage, bool> inner);
}
The IMessageHandler
can now check the message and then decide whether or not to call onto the inner
handler.
Something that would be useful here would be to be able to fuse two message handlers together to form a new handler:
public static class MessageHandlerExtensions
{
public static IMessageHandler Then(this IMessageHandler derived, IMessageHandler baseImpl)
=> new ComposedMessageHandler(derived, baseImpl);
private sealed class ComposedMessageHandler : IMessageHandler
{
private readonly IMessageHandler _derived;
private readonly IMessageHandler _baseImpl;
public ComposedMessageHandler(IMessageHandler derived, IMessageHandler baseImpl)
{
_derived = derived;
_baseImpl = baseImpl;
}
public bool Parse(IMessage message, Func<IMessage, bool> inner)
=> _derived.Parse(message, msg => _baseImpl.Parse(msg, inner));
}
}
Now, if we have a list of IMessageHandler
s we can combine them all with something like (depending on what order you want them applied) handlers.Aggregate((d, b) => b.Then(d))
. (AKA, IMessageHandlers
are monoidal).
You might notice that that's a lot of typing. It would be nice to be able to write this instead, replacing all the code in the last block (using my proposed syntax):
public static class MessageHandlerExtensions
{
public static IMessageHandler Then(this IMessageHandler derived, IMessageHandler baseImpl)
=> new IMessageHandler with {
bool Parse(IMessage message, Func<IMessage, bool> inner)
=> derived.Parse(message, msg => baseImpl.Parse(msg, inner));
};
}
Aside: compare the F# which would be something like:
let combine (derived : IMessageHandler) (baseImpl : IMessageHandler) =
{ new IMessageHandler with
member __.Parse msg inner =
derived.Parse msg (fun m -> baseImpl.Parse m inner) }
Finally, we then need a way to augment an IParseMessages
with the combined IMessageHandler
, to produce a new fused IParseMessages
that we can pass around. In current C# this could be something like:
public static class MessageParserExtensions
{
public static IParseMessages Augment(this IParseMessages me, IMessageHandler handler)
=> new AugmentedMessageParser(handler, me);
}
sealed class AugmentedMessageParser : IParseMessages
{
private readonly IMessageHandler _handler;
private readonly IParseMessages _impl;
public AugmentedMessageParser(IMessageHandler handler, IParseMessages impl)
{
_handler = handler;
_impl = impl;
}
public bool Parse(IMessage message) => _handler.Parse(message, _impl.Parse);
}
Using the proposed syntax this could be reduced to the much smaller:
public static class MessageParserExtensions
{
public static IParseMessages Augment(this IParseMessages me, IMessageHandler handler)
=> new IParseMessages with {
bool Parse(IMessage message) => handler.Parse(message, me.Parse); };
}
Again, to compare with F# this would be:
let augment (me : IParseMessages) (handler : IMessageHandler) =
{ new IParseMessages with
member __.Parse msg = handler.Parse msg me.Parse}
I think this reduction in boilerplate would be very useful.
from roslyn.
I've literally wanted this feature for years... If it worked then say goodbye to fakes, mocks and generated decorators!
This might give new lease of life to anonymous types since, as far as I can tell, they're about to be completely superseded by tuples. Giving them the ability to implement interfaces would give them a reason to continue existing.
from roslyn.
I don’t know what you may be missing, but I believe that local class declarations give you the full power in a much more readable and clear form.
from roslyn.
Are there public APIs in Java that have anonymous types?
No, there are public APIs throughout Java and the Java ecosystem that expose interfaces for use as callbacks, and the idiomatic (and natural) approach to implementing them is via anonymous types.
https://github.com/google/guava/wiki/FunctionalExplained
https://hc.apache.org/httpcomponents-asyncclient-ga/quickstart.html
https://commons.apache.org/proper/commons-functor/examples.html
https://github.com/Netflix/Hystrix/wiki/How-To-Use#Reactive-Execution
http://reactivex.io/documentation/operators/filter.html
https://developer.android.com/guide/topics/ui/ui-events
https://developer.android.com/guide/topics/location/strategies
https://docs.oracle.com/javafx/2/events/handlers.htm
https://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html
http://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-9
https://jersey.github.io/documentation/latest/rx-client.html
https://github.com/AsyncHttpClient/async-http-client#using-custom-asynchandlers
I honestly think you'd find it pretty difficult to find API docs that would suggest implementing callback interfaces using local types over anonymous types.
from roslyn.
very disappointed that this was closed without reason.
from roslyn.
I don’t know what you may be missing, but I believe that local class declarations give you the full power in a much more readable and clear form.
But with unnecessary boilerplate, even by Java standards. In my experience local type declarations are nearly non-existent in the Java ecosystem, but anonymous classes are exceptionally common. This was especially true leading up to Java finally getting lambdas. If you look at any of the helper packages for Java that deal in functional concepts or callbacks they all use anonymous types, including those from Google, Netflix, Apache, Amazon, etc., both internally and in any example they provide for using their APIs.
I could probably count the number of times I've seen local declarations in the wild on one hand, at best. The only times I've ever reached for them myself was to emulate closures in lambdas due to Java forcing all enclosed locals to be effectively final. With Java 10 that's no longer necessary and I will refactor all of that code to using anonymous classes instead.
public IDisposable Foo() {
class Foo : IDisposable {
public void Dispose() {
Console.WriteLine("Disposed!");
}
};
return new Foo();
}
vs.
public IDisposable Foo() => new IDisposable {
void Dispose() => Console.WriteLine("Disposed!");
};
There's nothing unreadable about that second example. If anything I think it does a much better job of focusing on what it actually does.
from roslyn.
We have no expectation of ever doing anything like this.
Well, boo to you.
from roslyn.
Furthermore, if Java/Android interop is given as one of the reasons for adopting default interface members (of which I am in favor, regardless of the justification), then I can state that the same interop is a good reason to adopt anonymous classes.
As @errorx666 stated, Android dev is interface-driven for callbacks. This makes them cumbersome to use from C# as you have to declare an entire separate class. Local types help, but that's still a lot of ceremony to declare and instantiate to effectively emulate what would be an exceptionally verbose lambda. To improve that situation from C# I would recommend that anonymous types are considered. Even better would be to allow lambda syntax with interfaces with exactly one required method (or also expand that out to abstract types, like Scala supports). Incidentally, poking at the Android docs, they clearly favor anonymous classes also.
from roslyn.
t00 proposed:
interface IPerson { string Name { get; } bool IsDeceased { get; } } interface IEmployee { string Boss { get; } } IPerson GetPerson() { return new : IPerson, IEmployee { Name = "John", IsDeceased = true, Boss = "OK", ExtraProperty = 123 }; }
Sorry, but the syntax just seem wrong for the C# language. It's to laxed like JavaScript is and takes away from the strong-typing we've come to expect. While I believe C# could benefit from adding scaffolding to anonymous types (albeit via interfaces or other), I don't think this proposed code example is the way to go about it.
from roslyn.
I've been working with Xamarin for Android recently, and because the underlying API is Java based, you're generally expected to pass in an interface implementation where typical C# conventions would use delegates or lambdas.
In Java this is simple: use an anonymous class. In C#, you end up creating multiple unnecessary classes and it's very cumbersome.
from roslyn.
@rashadrivera there's no weak-typing used in that example. the example uses syntax similar to Object Initializers introduced in C# 3.0. Have you updated to C# 3.0 yet?
from roslyn.
I am skeptical of the property implementation syntax, I think it should be something like
return new : IPerson, IEmployee
{
Name => "John",
IsDeceased => true,
Boss => "OK",
ExtraProperty => 123
};
or
return new : IPerson, IEmployee
{
Name { get; } = "John",
IsDeceased { get; } = true,
Boss { get; } = "OK",
ExtraProperty { get; } = 123
};
because we are defining a type that implements the properties of the interfaces, where as in the case of anonymous types, the compiler is generating a type definition for us based on the names and values of the instantiation expression.
from roslyn.
Local type declarations are still on the table.
The most value I ever got from anonymous types in Java was a series of counterintuitive examples for the book Java Puzzlers.
from roslyn.
The reason anonymous types are not passable outside the scope where they are created is due to a lack of unification of types across assemblies in the runtime, not a design philosophy. Giving anonymous types an interface is a good idea. I believe it was proposed during the design for anonymous types but was outside the intent of the feature at the time.
from roslyn.
As anonymous classes are created with only getters available and only in the current scope this feature might be non-trivial to implement.
But implementation can happen in 2 stages, 1 for getter-only interfaces and 2 for getter and setter + methods.
I would say implementing only interfaces containing property getters would be a huge improvement and should not change anonymous constructor code apart from adding inheritance to the anonymous class.
Inheritance syntax should be explicit and any setter or method on the interface or missing property on the anonymous implementation should trigger an error:
interface IPerson
{
string Name { get; }
bool IsDeceased { get; }
}
interface IEmployee
{
string Boss { get; }
}
IPerson GetPerson()
{
return new : IPerson, IEmployee
{
Name = "John",
IsDeceased = true,
Boss = "OK",
ExtraProperty = 123
};
}
from roslyn.
This would be great to implement multiple action callbacks.. Image a class which downloads a file:
Callback Interface:
public interface IDownloadResultHandler {
void Success(string path);
void Fail();
}
Class:
public class FileDownloader {
public static void Download(string path, IDownloadResultHandler callback) {
// starts download on a second thread and returns but keeps handle to callback
....
}
internal static void downloadThread() {
...
if(success) {
this.callback.Success(pathOfFile);
}
else {
this.callback.Fail();
}
}
}
Later on this could be used like this
MyConsole console = new MyConsole();
FileDownloader.Download("/path/to/file", new : IDownloadResultHandler {
Success() { console.Write("Success"); }
Fail() { console.Write("Failed.."); }
});
Currently one has to implement a seperate class which implements the interface and pass the environment via a constructor parameter or inject it via dependency injection..
Having anonymous Implementations of interfaces could save us from a lot of boilerplate code.. Furthermore "Callbacks" could explicitly state if they support a different functionality by implementing a interface or not!
from roslyn.
I'm going to post another example just 'cause.
Here's some C#:
public Sink<TIn, TResult2> MapResult<TResult2>(Func<TResult, TResult2> projection)
=> new MappedResult<TResult2>(this, projection);
private sealed class MappedResult<TResult2> : Sink<TIn, TResult2>
{
private Sink<TIn, TResult> _sink;
private Func<TResult, TResult2> _projection;
public MappedResult(Sink<TIn, TResult> sink, Func<TResult, TResult2> projection)
{
_sink = sink;
_projection = projection;
}
public override ActiveSink<TIn, TResult2> Open() => new Impl(_sink, _projection);
private sealed class Impl : ActiveSink<TIn, TResult2>
{
private ActiveSink<TIn, TResult> _sink;
private Func<TResult, TResult2> _projection;
public Impl(Sink<TIn, TResult> sink, Func<TResult, TResult2> projection)
{
_sink = sink.Open();
_projection = projection;
}
public override TResult2 Result => _projection(_sink.Result);
public override void Dispose() => _sink.Dispose();
public override Task ProcessChunk(ReadOnlySpan<TIn> span, CancellationToken cancellationToken)
=> _sink.ProcessChunk(span, cancellationToken);
}
}
Here's the exact same thing using object expressions in F#:
member me.MapResult (projection : 'TResult -> 'TResult2) : Sink<'T, 'TResult2> =
{ new Sink<'T, 'TResult2>() with
override __.Open() =
let activeSink = me.Open() in
{ new ActiveSink<'T, 'TResult2> with
override __.Dispose() = activeSink.Dispose()
override __.ProcessChunk c ct = activeSink.ProcessChunk c ct
override __.Result with get() = projection activeSink.Result
}
}
Being able to close over variables in anonymous type definitions cuts down on a lot of boilerplate.
By comparison, here is the equivalent Java (with anonymous classes):
public <TResult2> Sink<TIn, TResult2> MapResult(Function<TResult, TResult2> f)
{
Sink<TIn, TResult> me = this;
return new Sink<TIn, TResult2>() {
public ActiveSink<TIn, TResult2> open() {
ActiveSink<TIn, TResult> activeSink = me.open();
return new ActiveSink<TIn, TResult2>() {
public TResult2 result() { return f.apply(activeSink.result()); }
public void close() { activeSink.close(); }
public void processChunk(TIn[] c) { activeSink.processChunk(c); }
};
}
};
}
And here's a hypothetical "C# with anonymous classes/object expressions":
public Sink<TIn, TResult2> MapResult<TResult2>(Func<TResult, TResult2> f)
{
var me = this;
return new Sink<TIn, TResult2> with {
override ActiveSink<TIn, TResult2> Open() {
var activeSink = me.Open();
return new ActiveSink<TIn, TResult2> with {
override TResult2 Result => f(activeSink.Result);
override void Dispose() => activeSink.Dispose();
override Task ProcessChunk(TIn[] c, CancellationToken ct)
=> activeSink.ProcessChunk(c, ct);
};
}
};
}
from roslyn.
Is it time to revisit this now that Record/Data construct solves most of the mention concerns?
Maybe this idea wasn't right for class interfaces, but it is for Record/Data interfaces.
from roslyn.
Note that records (#206) can implement interfaces. I think that satisfies the underlying need of this request.
from roslyn.
@gafter Can records be declared within method body? I think this request is about not polluting the namespaces and creating explicit named types, rather than creating immutable classes with compact syntax. I believe these are different.
from roslyn.
@alrz +1. Just use a comma for consistency. Isn't the return type+visibility redundant (unless internal interfaces make an appearance)?
return new ICustomer {
Name = "Jim",
Surname = "Bob",
IsValid() => true,
Foo = bar,
Baz() => false
};
from roslyn.
I have never written Java, so am I missing something? I still really want this for C#.
from roslyn.
@jbtibor dotnet/csharplang#130
from roslyn.
@jnm2 that´s not really the same thing.. anonymous types implementing an interface would allow you to pass them as a reference to multiple callbacks to a long running action / task.. Such a pattern is heavily used in Android in Java..
There are typically multiple things that could happen if you trigger some asynchronous actions.. If you only have one callback/delegate you have to have multiple parameters which are not used in all cases, passing an object which implements functions for that cases looks much cleaner / is more readable.
from roslyn.
that the same interop is a good reason to adopt anonymous classes.
Are there public APIs in Java that have anonymous types?
from roslyn.
Feature requests for C# can be opened in https://github.com/dotnet/csharplang
sounds like that would just be a waste of time:
We have no expectation of ever doing anything like this.
from roslyn.
There is:
dotnet/csharplang#2517
dotnet/csharplang#2298
from roslyn.
Being able to do something like
using (var itm = new {Name = "Jay"})
{
//Do stuff with itm knowing itm.Name would be disposed and any other IDIsposable properties in itm.
}
would be useful.
from roslyn.
I like the idea. Although anonymous types aren't meant to be passed outside the scope where they're created, interfaces are all about the contract so it doesn't matter much that the implementation is compiler-generated.
Per your suggestion about methods, it looks like C# 6 already blurs the line between methods and delegates (from a syntax standpoint), so maybe it's not such a far-fetched suggestion.
from roslyn.
Thinking out loud here, it seems that I could break my proposal in two:
- Allow anonymous objects to include methods and writeable properties.
- Allow anonymous objects to implement interfaces
Once the first is achieved, the second one should be straightforward.
To me, it is clear the idea is very useful and would reduce drastically the number "dumb" classes I need just to return models in interface driven code.
But it raises some questions:
- How to declare a writeable property in an anonymous object?
- If the property is writeable, does it require an initial value?
new {
// new modifier keyword?
readwrite Name = "foo",
readwrite string Name,
// no types, always infer from the value?
readwrite Name = default(string),
// no value implies it will be set later, hence writeable? - looks strange
string Name;
// borrow syntax from real properties?
string Name { get; set; },
Name { get; set; } = "initial value",
// or imply the get and require only the set?
string Name { set; },
Name { set; } = "initial value",
}
- And If I know beforehand the declaration type, could it infer the interface?
interface IPerson {
string Name { get; set; }
bool IsDeceased { get; set; }
}
IPerson GetPerson() {
return new {
Name = "John"
};
}
This would create some form of "duck typing", making like implementing one-time used interfaces easier.
interface ISystemClock {
DateTimeOffset Now()
}
iocContainer.Resolve<ISystemClock>().With(new { Now() => DateTimeOffset.Now });
from roslyn.
I duped this (as linked above), with an alternative syntax.
from roslyn.
+1
from roslyn.
+1
from roslyn.
+1
@nvivo Are you requesting specifically interface implementations or subtyping as well?
Depending on that #1728 might be a duplicate.
Also what do you mean by saying "interface driven design"?
Relevant quote:
http://www.jot.fm/issues/issue_2005_07/article1.pdf
Note that as generalizations, interfaces compete with abstract classes. In fact, in
practice interfaces and abstract classes are sometimes used as if they were the same
concept. However, since abstract classes have the potential to pass on implementation to
their subclasses, they should be used if (and only if) the relationship to the subclasses is
genetic, i.e., if it is (or at least could be) based on the inheritance of internal structure, that
is, implementation. If on the other hand the relationship is based on pure function (or,
weaker still, on sameness of protocol), interfaces should be used. For instance, a linked
list and a dynamic array would normally not be genetically related (i.e., have no common
pieces of implementation), yet they share the interface of lists (specifying sequential
access to their elements).
from roslyn.
+1
from roslyn.
+1
Also thinking out loud here.
Concern 1
What about methods? One thing I've done for mock objects (without a mocking framework) in the past is to store a delegate that has the matching signature in a private field and invoke that from the interface. E.g.
interface ICustomer {
string Name { get; }
string Surname { get; }
bool IsValid();
}
return new ICustomer() {
Name = "Jim",
Surname = "Bob",
IsValid = () => true
};
This would roughly compile to:
class ICustomerAnyonymousType {
public string Name { get; set; }
public string Surname { get; set; }
public Func<bool> IsValidImplementation { get; set; } // Or a private field
public bool IsValid() {
var impl = IsValidImplementation;
if (impl == null) throw new NotImplementedException();
return impl();
}
}
return new ICustomerAnyonymousType() {
Name = "Jim",
Surname = "Bob",
IsValidImplementation = () => true
};
Concern 2
What about default values? I might not want to provide an implementation for a method or omit a property. Possibly:
return new default ICustomer() {
Name = "Jim"
};
Surname
would return null
, and IsValidImplementation
would be set to null
(causing a NotImplementedException
). If default
is omitted all members must be provided (else there will be compile failure).
Why?
Unit tests and mocking. For trivial scenarios (not involving abstract or sealed classes) you could mock your objects as follows:
[Fact]
public void DisplayCustomer_ValidateCalled()
{
var validateCalled = false;
var customer = new ICustomer() {
Name = "Jim",
Surname = "Bob",
IsValid = () => validateCalled = true
}
sut.Display(customer);
Assert.True(validateCalled);
}
[Fact]
public void DeleteCustomer_Deleted()
{
var customer = new default ICustomer() {
Name = "Jim",
Surname = "Bob"
// Omit IsValid because it is never called.
// NotImplementedException would be thrown if it was
// somehow called.
}
sut.Deleted(customer);
Assert.Null(sut.GetCustomer(customer));
}
from roslyn.
return new ICustomer() { Name = "Jim", Surname = "Bob", IsValid = () => true };
It's not clear that you're initializing a property of type Func<bool>
or implementing the method. I think this should be done in a more explicit way like:
return new ICustomer {
public string Name => "Jim";
public string Surname => "Bob";
public bool IsValid() => true;
};
from roslyn.
This looks more like a initialization block rather than class declaration. Also it could be implemented as a nested local type (#259) so naturally you would expect anonymous classes as well:
return new BaseClass() {
public override bool IsValid() => true;
...
};
PS: comma was a typo, sorry.
from roslyn.
Within context of this issue/feature it's about anonymous types and we should likely extend syntax instead of breaking existing syntax.
from roslyn.
@ArlZ, these two look exactly the same to me:
IsValid() => true
public override bool IsValid() => true
adding modifiers doesn't change that, only makes more verbose.
from roslyn.
@nvivo I think @alrz is bringing in inspiration across from #259, which could succeed/replace this feature - but that has already been specced over on that issue. I prefer the more succinct syntax, like you, as anything more is entirely redundant and doesn't look like the current anonymous types at all.
from roslyn.
I'm talking about a more general feature like "implementing interfaces anonymously" instead of "anonymous types implementing interfaces". I borrowed all this from Java, though.
from roslyn.
It anonymity really important? Compared to local (within a block) class declaration as an alternative way of handling this. It is nice that this lets you stay in an expression context, it is true, but I do not think the use cases are really simplified much.
from roslyn.
It anonymity really important?
For Linq I'd assume it would be crucial.
public IEnumerable<ICustomer> GetCustomers() {
return from c in db.Customers
select new {
Name = c.Name,
Surname = c.Surname
};
}
In addition:
- Syntax already exists for anonymous types - why not re-use it instead of adding cruft?
- Syntax already exists for classes - why not re-use it for block-scope classes?
- Using pseudo-anonymous block-scope class initializers would result in two forms of syntax for exactly the same thing. E.g. The same problem already exists in C#:
- When should you use a lambda?
- When should you use a anonymous delegate?
- What value do the publicity specifiers add? YAGNI.
- What value do the return types add? YAGNI.
Does inventing new syntax here for anonymous-but-no-so-anonymous-types add anything at all? Even just one thing? Versus adding either nothing (if method declarations are not supported) or re-using the lambda grammar (if method declarations are supported); both also have significantly less keystrokes, significantly less indentation and are far easier to human-parse. Less syntax makes a language good, not more. Once you have added syntax you can never remove it, in opposition: using existing syntax should be largely familiar to experienced developers.
from roslyn.
@Porges A lot of that boilerplate could be also removed by using a record
(part of #206).
from roslyn.
It anonymity really important? Compared to local (within a block) class declaration as an alternative way of handling this. It is nice that this lets you stay in an expression context, it is true, but I do not think the use cases are really simplified much.
@gafter Are local type declarations still on the table? To me this is all about scoping.
from roslyn.
In addition to scoping, I think capturing generic parameters could make this quite useful.
from roslyn.
from roslyn.
@alrz Thanks!
from roslyn.
I does not have to be perfect , it is anonymous types after all , i think implementing the interface geter without extra syntax like in the (t00 commented on Jul 24, 2015) cover 90% of the day to day need.
the idea is not to have full functional class, to do that just use a private class, we need to have ability to pass data when interface required, just like what we do in anonymous type in linq ,if the code try to consume the set method ,show an error or throw an Exception at run time, just like anonymous types.
tuple that can't implementing interface, will not solve the problem.
from roslyn.
I still think this is a very required feature, but this issue has been closed and I don't believe the team will respond this issue again.
Someone with time to discuss should open a new issue proposing a simpler version of this and see what can get out of it.
from roslyn.
I'm willing to give that a try first.
from roslyn.
@gafter Are there local classes in C#? Or this is a future feature? I agree that local classes would make anonymous interface implementations redundant.
from roslyn.
@Spacefish And well I know it. I was answering @jbtibor's question, "Are there local classes in C#? Or this is a future feature?"
from roslyn.
@RUSshy See the comment above: #13 (comment)
We have no expectation of ever doing anything like this.
Also, this kind of issue now belongs to the csharplang repo, and there is a very similar request already opened there: dotnet/csharplang#1542.
from roslyn.
Similar but not quite. It might be worth opening a separate issue. I agree that it doesn't seem likely that it will happen given the tepid response from some team members, but I do think that they would be very useful especially when it comes to Android interop.
from roslyn.
Feature requests for C# can be opened in https://github.com/dotnet/csharplang
from roslyn.
sounds like that would just be a waste of time:
You never know. Someone might champion it. If it is not opened, it certainly won't happen though.
from roslyn.
Feature requests for C# can be opened in https://github.com/dotnet/csharplang
sounds like that would just be a waste of time:
We have no expectation of ever doing anything like this.
"We will never make a 32-bit operating system."
Bill Gates (speaking at the launch of MSX in 1989).
from roslyn.
This should be brought to C#!
Give your votes here:
dotnet/csharplang#4301
from roslyn.
Being able to do something like ... would be useful.
Under what circumstances would that be better than using
on the disposables themselves? Even with the original proposal here there's nothing to suggest that the implemented interface would be automatically delegated to any, let alone all, of the members of the anonymous type.
from roslyn.
Well in one place is in Observable.Using call. Create an anonymous object wrapping different items to use as resources and in the Observable factory part can use the resource object items.
from roslyn.
I understand I can create a class and write the code but having anonymous objects able to implement IDisposable and have it create disposable implimentation that disposes items that are disposable would be useful.
I get the problem of creating an anonymous object with a member pointing to something IDisposable that exists outside of anonymous object and then that object is disposed because the anonymous object was disposed.
from roslyn.
Maybe like key keyword in vb when creating a comparable anonymous object, a new keyword could be out in front of members we want disposed. If that keyword is used at all in that anonymous creation then it is IDisposable and items marked by keyword get added to items that are disposed.
var x = new { Dispose SomeIDisposable x = Blaaa}
Something like that.
from roslyn.
I'd suggest opening a new discussion on the csharplang repository if that's something you want to suggest. This particular issue is already closed and this repository isn't used to propose new language features anymore.
from roslyn.
@tmat has started a discussion on this: dotnet/csharplang#6049
from roslyn.
Related Issues (20)
- Bad performance in CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer with System.Text.Json source generator HOT 12
- [Automated] PRs inserted in VS build main-35214.134
- Use interpolated string handler for string concat HOT 3
- Using SuppressMessage on a const declaration causes Diagnostic analyzer runner interal error
- `CSharpWrappingCodeRefactoringProvider` encountered an error and has been disabled
- `CSharpMergeNestedIfStatementsCodeRefactoringProvider` encountered an error and has been disabled
- `CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider` encountered an error and has been disabled
- Usage of Activator.CreateInstance won't show in references on the constructor, so there is misleading info!
- Automatic exception xml tag when using static class such as ArgumentNullException HOT 2
- Allow the Visual Studio "Sync Namespaces" tool to work at the folder level, not just Project and Solution.
- Refactoring suggestion -> Move to new file needs a confirmation dialog
- Reenable BC30645ERR_InvalidOptionalParameterUsage1b
- [Automated] PRs inserted in VS build feature.debugger.main-35215.202
- Inconsistent report of CS8156 when using generically constrained interfaces and [UnscopedRef]
- Sourcelink does not debug merged partial classes
- Advanced analysis options are unreliable, confusing and poorly documented
- EditorConfig "modern" vs legacy priority revert related documentation updates
- CS8344 error even with C# 13 (ref in iterators/async) HOT 1
- Editor and debugger don't agree on breakpoint range
- CS8602 should look deeper ("Dereference possibly null reference") HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from roslyn.