2017-01-19 1 views
0

Disons que j'ai le code qui ressemble à ceci:Comment puis-je accéder à un champ d'un type anonyme stocké dans une variable objet?

public struct Foo 
    { 
     public object obj; 
     public Foo(int val) 
     { 
      obj = new { 
       bar = val 
      }; 
      Console.WriteLine(obj.bar); // Can't access bar. 
     } 
    } 

Normalement, je vois des types anonymes stockées dans des variables implicitement typées et leurs champs peuvent ACCESSIBLES très bien dans ce cas. Mais je ne peux pas taper implicitement avec var dans ce cas car obj est un champ dans une structure et ne peut apparemment pas être initialisé. Alors, comment puis-je accéder au champ bar?

+0

Quand une structure a-t-elle obtenu un constructeur par défaut? LOL – ViVi

+0

Que voulez-vous dire? Voulez-vous dire qu'il ne devrait pas compiler sans donner à struct un constructeur sans paramètre explicitement défini? Parce qu'il compile sans un. –

Répondre

2

Utilisez le mot-clé dynamic:

public struct Foo 
{ 
    public dynamic obj; 
    public Foo(int val) 
    { 
     obj = new 
     { 
      bar = val 
     }; 
     Console.WriteLine(obj.bar); // is accessible now 
    } 
} 
2

ce que vous faites ne compilera pas parce que object n'a pas une définition pour bar. Si, pour une raison quelconque, vous devez conserver une référence à un type anonyme, vous devrez utiliser dynamic. Notez que vous n'aurez pas de sécurité de type à la compilation et qu'il y aura peut-être un léger problème de performance pour cela.

public struct Foo 
{ 
    public dynamic obj; 
    public Foo(int val) 
    { 
     obj = new { 
      bar = val 
     }; 
    } 

    public void WriteMyFooBar() 
    { 
     Console.WriteLine(obj.bar); 
    } 
} 

Cependant, on ne conteste l'utilisation d'un type anonyme ici au lieu de définir une interface qui fournit au moins un getter pour bar.

2

Soit vous pouvez essayer coulée obj d'objet de type à dynamic puis accéder à la valeur requise, ou vous pouvez changer le type de obj-dynamic.

Essayez ceci:

Console.WriteLine(((dynamic)obj).bar)); 
1

Vous pouvez utiliser dynamic comme d'autres l'ont suggéré ou laquelle vous pouvez utiliser une méthode "prototype", comme ceci:

public struct Foo 
{ 
    public object obj; 
    public Foo(int val) 
    { 
     obj = new { 
      bar = val 
     }; 
     this.Use(new { bar = 0 }, x => Console.WriteLine(x.bar)); 
    } 
    public void Use<T>(T prototype, Action<T> action) 
    { 
     action((T)this.obj); 
    } 
} 

Cela fonctionne très bien.