2009-10-07 5 views
2

Vous pouvez appeler un membre statique sur un type lorsque je n'ai qu'un paramètre générique. Par exemple, si j'ai quelque chose comme çaAppel de membre statique lorsque vous avez uniquement un paramètre générique

public Get<T>(int id) 
{ 
    // I would like to do this 
    string s = T.SomeMethodName(); 
} 

je pouvais le faire comme ça, mais est un peu « dégueu », et il n'a pas d'importance si elle est statique ou non. Ou je pourrais utiliser la réflexion comme suggéré par Yuriy.

ISomeKnownInterface i = (ISomeKnownInterface) new T(); 
string s = i.SomeMethodName(); 

Alors question est maintenant qui est meilleure approche, la création d'une nouvelle instance de réflexion à l'aide

public TFormDto Get<TFormDto>(int entityId) where TFormDto : AbstractEntityFormDto, new() 
     { 
// create new instance 
      AbstractEntityFormDto a = (AbstractEntityFormDto) new TFormDto(); 
      string entityName = a.GetEntityFullTypeName(); 

// use reflection 

      Type type = typeof(TFormDto); 
      string entityName = type.GetMethods(BindingFlags.Public | BindingFlags.Static) 
       .Single(m => m.Name == "GetEntityFullTypeName") 
       .Invoke(null, null); 

Répondre

1

Ce ne serait pas juste toujours AbstractBaseClass.GetFullName(). Sinon, vous devez utiliser la réflexion sur T pour obtenir la méthode statique d'une autre classe. This peut être utile.

Ce qui suit est un exemple simple:

class TestClass 
{ 
    public static void Hello() 
    { 

     Console.WriteLine("World!!!"); 
    } 
} 

public static void Test<T>() where T : class 
{ 
    Type type = typeof(T); 
    type.GetMethods(BindingFlags.Public | BindingFlags.Static) 
     .Single(m => m.Name == "Hello") 
     .Invoke(null, null); 

}  

Avec votre échantillon, je suppose que vous savez que les interfaces ne sont pas des méthodes statiques. J'ai supposé que vous vouliez dire que vous aviez une interface qui a une signature pour la méthode statique et qu'une classe implémentant cette interface n'appellerait que la méthode statique de l'implémentation. Cela fonctionnerait aussi bien, mais vous n'êtes pas sûr que la statique correcte sera appelée et assurez-vous que T a une contrainte sur cette interface, pas seulement new().

+0

Oui, ce serait. Il me reste à essayer de définir une statique abstraite, ce qui n'est pas autorisé. – epitka

+0

Invoquant la méthode par réflexion comme ceci soit plus rapide que de faire quelque chose comme ça. Il est un peu malchanceux de le faire comme ça, mais bon c'est le code framework AbstractEntityFormDto v = (AbstractEntityFormDto) new TFormDto(); chaîne s = v.EntityFullTypeName; – epitka

+0

Pouvez-vous modifier votre question, je suis confus au sujet de ce que vous venez d'écrire dans ce format. –

1

Le problème est qu'il n'y a aucune garantie que T a une méthode membre statique nommée SomeMethodName. Si vous voulez appeler AbstractBaseClass.SomeMethodName, alors faites-le. La raison pour laquelle cela est impossible est une extension de la discussion static interface methods.

+0

A défaut nous n'avons pas de contrainte pour la méthode sur paramètre générique. Cela résoudrait mon problème. – epitka

0

Il n'y a aucun moyen de le faire sans utiliser la réflexion. Pour appeler une méthode statique, vous devez toujours spécifier le type réel.

Si vous souhaitez améliorer la sécurité au moment de la compilation de votre code, essayez d'éviter la réflexion. Rendez la méthode non statique et placez-la dans une interface. Ce serait le plus probablement (je ne connais pas votre problème) être la solution la plus propre.

J'ai fait pas mal de membres non statiques juste pour bénéficier des interfaces et du polymorphisme. Parfois, j'implémente quelque chose de similaire au modèle singleton (par exemple, une propriété statique pour obtenir une instance), ou j'appelle simplement le constructeur par défaut pour obtenir une instance et je le passe comme argument.

interface ISomeInterface 
{ 
    string SomeMethodName(); 
} 

class SomeImplementation : ISomeInterface 
{ 
    public static Instance { get { return new SomeImplementation(); } } 

    public string SomeMethodName() 
    { 
    // implementation of SomeMethodName 
    } 
} 

public Get(ISomeInterface i) 
{ 
    string s = i.SomeMethodName(); 
} 

public Example() 
{ 
    Get(SomeImplementation.Instance); 
} 

Vous pouvez également créer la nouvelle instance dans la méthode générique, vous pouvez également spécifier que vous avez besoin d'un constructeur par défaut:

public Get<T>() where T : ISomeInterface, new() 
{ 
    T instance = new T(); 
    string s = instance.SomeMethodName(); 
} 

public Example() 
{ 
    Get<SomeImplementation>(); 
} 
+0

Le problème est que je n'ai pas d'instance juste un paramètre générique. Donc, fondamentalement, mes options sont de renouveler l'instance et d'obtenir la valeur ou d'utiliser la réflexion. – epitka

+0

Vous ne pouvez pas changer l'interface de votre méthode avec le paramètre générique? –

+0

Dans ce cas je ne peux pas changer la signature de la méthode, elle doit avoir un paramètre générique. – epitka

Questions connexes