2009-04-03 9 views
2

Comment puis-je définir une méthode, par ex. void doSuff() dans un type anonyme? Toute la documentation que je peux trouver n'utilise que des listes de propriétés anonymes strictement limitées aux propriétés. Puis-je même définir une méthode dans un type anonyme?Comment définir une méthode dans un type anonyme?

EDIT: OK, un rapide coup d'œil aux réponses très rapides me dit que c'est impossible. Est-il possible de construire dynamiquement un type et d'ajouter une méthode anonyme à une propriété de délégué sur ce type? Je suis à la recherche d'un moyen de C# pour accomplir ce que le code JavaScript suivant fait:

... 
person.getCreditLimit = function() { ... } 
... 
+0

Beaucoup de réponses différentes pour celui-ci, apparemment . Certains disent que vous pouvez, certains disent que vous ne pouvez pas. Veuillez accepter la bonne réponse dans votre cas. Les esprits curieux veulent savoir. – SirDemon

Répondre

5

Vous absolument peut, avec des délégués:

Action action = MethoThatDoesSomething; 
var obj = new 
      { 
       DoSomething = action 
      }; 

obj.DoSomething(); 

J'ai essayé avec un lambda dans le new { ... } et cela n'a pas fonctionné, mais ce qui précède est totalement bien.

3

Tu ne peux pas, au moins pas à .NET 3.5.

+0

Et pour clarifier pour l'OP: vous ne pouvez faire * rien * à un type anonyme; pas d'interfaces, pas de classe de base, pas de méthodes, pas d'attributs, pas de rien. Sauf les propriétés etc que le compilateur fournit. –

+0

C'est nul! Et .NET 4.0? – ProfK

+0

Il n'y a rien de prévu pour C# 4.0, et je doute qu'on verra jamais cela (je ne peux même pas imaginer comment vous définiriez une méthode sur un type anonyme, une construction de méthode d'extension bizarre?).Mais, pour être juste, l'équipe de conception de C# est beaucoup plus intelligente et intuitive que moi;) – Razzie

0

Vous ne pouvez pas. Mais voici ce que vous pouvez essayer:

var test = new { Foo = new Func<string>(() => "hello") }; 
test.Foo.Invoke(); 
0

Vous ne pouvez pas. Les types Anonymouse contiennent uniquement des propriétés avec des modificateurs get publics et des remplacements des méthodes GetHashCode(), Equals() et ToString().

var myclass = new { Name = "Andy", Location = "Bellingham", Sector = 0, }; 

De réflecteur:

[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; 
     } 
    } 
} 
+0

Pour C#, oui. Mais les balises incluent .NET - où ce n'est pas toujours vrai; Les types anonymes VB peuvent avoir des accesseurs définis. –

+0

Je n'avais jamais entendu parler de VB. Merci, – andleer

+0

Ah, les souris ninja à nouveau. –

8

Eh bien, vous pouvez. Avec les délégués, vous traitez simplement les méthodes comme des données:

var myMethods = from x in new[] { "test" } 
       select new { DoStuff = new Func<string>(() => x) }; 

var method = myMethods.First(); 
var text = method.DoStuff(); 

D'après vous, quelle est la valeur de "text"? Avec les types <> et Func <> génériques vous pouvez mettre (presque) tout ce que vous voulez dedans. Presque, parce que vous ne pouvez pas pour d'autres propriétés par exemple l'accès sur le type anonyme, comme ceci:

var myMethods = from x in new[] { "test" } 
       select new { Text = x, DoStuff = new Func<string>(() => Text) }; 
+0

Cette méthode peut-elle fermer sur des champs du type anonyme? J'en doute un peu, mais des fonctions anonymes imbriquées pourraient être exploitées pour simuler ceci (après tout, c'est ainsi que les langages fonctionnels implémentent les classes). –

+0

Très bonne idée! Juste une note que les méthodes seront effectivement statiques. – leppie

+0

@konrad, je pense que ce pourrait être possible, je vais essayer! – leppie

1

Qu'en est-ce:

 var anonType = new 
     { 
      FirstName = "James", 
      LastName = "Bond", 
      FullName = new Action<string, string>(
       (x, y) => 
        { 
         Console.WriteLine(x + y); 
        })     
     }; 

     anonType.FullName("Roger","Moore"); 

Fondamentalement utilisant un Lambda pour le délégué

0

Vous pouvez:

// 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(); 

Si vous ne voulez pas déclarer un type de délégué, vous pouvez utiliser System.Func <>:

var Obj = new { 
    MyFunc = new Func<string>(delegate() { return "yee-haw"; }) 
}; 
MessageBox.Show(Obj.MyFunc()); 
Questions connexes