How do I go about defining a method, e.g. void doSuff() in an anonymous type? All documentation I can find uses only anonymous restricted basically to property lists. Can I even define a method in an anonymous type?
EDIT: OK, a quick look at very quick answers tells me this is impossible. Is there any way at all to construct a type dynamically and add an anonymous method to a delegate property on that type? I'm looking for a C# way to accomplish what the following JavaScript does:
...
person.getCreditLimit = function() { ... }
...
-
You cant, at least not up to .NET 3.5.
Marc Gravell : And to clarify for the OP: you can't do *anything* to an anonymous type; no interfaces, no base class, no methods, no attributes, no nothing. Except the properties etc that the compiler provides.ProfK : That sucks! And .NET 4.0?Razzie : There's nothing planned for C# 4.0, and I doubt we will ever see this (I can't even imagine how you'd define a method on an anonymous type, some weird Extension Method construction?). But, to be fair, the C# design team is much much smarter and intuitive than me ;)Marc Gravell : Why does that "suck"? If you want classes with more features, declare it yourself...Jon Skeet : +1 for Marc's comment.ProfK : @Marc, it does not really suck that badly - I was being overly expressive, but if a type (i.e. precedented by named types) can have method members, then I would expect an apparent, except for naming, equivalent of a type, i.e. the anonymous type, to have method members.ProfK : Surely whatever allows a `dynamic` type to receive a group of method members from an untyped source object could be applied to anonymous types? -
You can't. But here is what you could try:
var test = new { Foo = new Func<string>(() => "hello") }; test.Foo.Invoke(); -
You can't. Anonymouse types only contain properties with public get modifiers and overrides of the GetHashCode(), Equals() and ToString().
var myclass = new { Name = "Andy", Location = "Bellingham", Sector = 0, };From reflector:
[CompilerGenerated, DebuggerDisplay(@"\{ Name = {Name}, Location = {Location}, Sector = {Sector} }", Type="<Anonymous Type>")] internal sealed class <>f__AnonymousType0<<Name>j__TPar, <Location>j__TPar, <Sector>j__TPar> { // Fields [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly <Location>j__TPar <Location>i__Field; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly <Name>j__TPar <Name>i__Field; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly <Sector>j__TPar <Sector>i__Field; // Methods [DebuggerHidden] public <>f__AnonymousType0(<Name>j__TPar Name, <Location>j__TPar Location, <Sector>j__TPar Sector) { this.<Name>i__Field = Name; this.<Location>i__Field = Location; this.<Sector>i__Field = Sector; } [DebuggerHidden] public override bool Equals(object value) { var type = value as <>f__AnonymousType0<<Name>j__TPar, <Location>j__TPar, <Sector>j__TPar>; return ((((type != null) && EqualityComparer<<Name>j__TPar>.Default.Equals(this.<Name>i__Field, type.<Name>i__Field)) && EqualityComparer<<Location>j__TPar>.Default.Equals(this.<Location>i__Field, type.<Location>i__Field)) && EqualityComparer<<Sector>j__TPar>.Default.Equals(this.<Sector>i__Field, type.<Sector>i__Field)); } [DebuggerHidden] public override int GetHashCode() { int num = 0x5fabc4ba; num = (-1521134295 * num) + EqualityComparer<<Name>j__TPar>.Default.GetHashCode(this.<Name>i__Field); num = (-1521134295 * num) + EqualityComparer<<Location>j__TPar>.Default.GetHashCode(this.<Location>i__Field); return ((-1521134295 * num) + EqualityComparer<<Sector>j__TPar>.Default.GetHashCode(this.<Sector>i__Field)); } [DebuggerHidden] public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append("{ Name = "); builder.Append(this.<Name>i__Field); builder.Append(", Location = "); builder.Append(this.<Location>i__Field); builder.Append(", Sector = "); builder.Append(this.<Sector>i__Field); builder.Append(" }"); return builder.ToString(); } // Properties public <Location>j__TPar Location { get { return this.<Location>i__Field; } } public <Name>j__TPar Name { get { return this.<Name>i__Field; } } public <Sector>j__TPar Sector { get { return this.<Sector>i__Field; } } }Marc Gravell : For C#, yes. But the tags include .NET - where this is not always true; VB anonymous types can have set accessors.Andrew Robinson : Never knew that about VB. Thanks,Jeff Yates : Ah, ninja mice again. -
Well, you can. With delegates you just treat methods as data:
var myMethods = from x in new[] { "test" } select new { DoStuff = new Func<string>(() => x) }; var method = myMethods.First(); var text = method.DoStuff();What do you think the value of "text" is?
With the Action<> and Func<> generic types you can put (almost) whatever you want in there. Almost, because you cannot for instance access other properties on the anonymous type, like this:
var myMethods = from x in new[] { "test" } select new { Text = x, DoStuff = new Func<string>(() => Text) };Konrad Rudolph : Can this method close over fields in the anonymous type? I rather doubt it, but nested anonymous functions might be exploited to simulated this (after all, this is how functional languages implement classes).leppie : Very good idea! Just a note that the methods will effectively be static though.leppie : @konrad, I think it might be possible, im gonna try it!Peter Lillevold : You mean if the method can do stuff with the other properties on the anonymous type? I doubt so too...Peter Lillevold : @leppie, awaiting your results :)leppie : No go, brain tired now! So much easier in Scheme! -
What about this:
var anonType = new { FirstName = "James", LastName = "Bond", FullName = new Action<string, string>( (x, y) => { Console.WriteLine(x + y ); }) }; anonType.FullName("Roger","Moore");Basically using a Lambda for the delegate
-
You absolutely can, with delegates:
Action action = MethoThatDoesSomething; var obj = new { DoSomething = action }; obj.DoSomething();I tried with a lambda in the
new { ... }and that didn't work, but the above is totally fine. -
You can:
// this line should be in class body, not in method delegate void MyDelegate(); var Obj = new { MyDel = new MyDelegate(delegate() { MessageBox.Show("yee-haw"); }) }; Obj.MyDel();If you don't want to declare a delegate type, you can use System.Func<>:
var Obj = new { MyFunc = new Func<string>( delegate() { return "yee-haw"; }) }; MessageBox.Show(Obj.MyFunc());
0 comments:
Post a Comment