2014-05-16 3 views
1

Pourquoi la ligne marquée par //Dont work in the bottom of the code ne se compile-t-elle pas?Comment appeler une méthode d'une autre classe à partir d'une méthode générique?

Je veux réutiliser la méthode WriteMessage avec différentes classes, j'essaie d'utiliser generics, mais je ne suis pas sûr de savoir comment l'utiliser.

class ClassOne 
{ 
    public string MethodOne() 
    { 
     return ("ClassOne"); 
    } 

    public string MethodTwo() 
    { 
     return ("ClassOne -MethodTwo "); 
    } 
} 

class ClassTwo 
{ 
    public string MethodOne() 
    { 
     return ("ClassTwo"); 
    } 

    public string MethodTwo() 
    { 
     return ("ClassOne -MethodTwo "); 
    } 
} 

class Program 
{ 
    private static void Main() 
    { 
     var objectOne = new ClassOne(); 
     WriteMessage(objectOne); 

     var objectTwo = new ClassTwo(); 
     WriteMessage(objectTwo); 
     Console.ReadKey(); 
    } 

    public static void WriteMessage<T>(T objectA) 
    { 
     var text = objectA.MethodTwo(); //Dont Work 
     Console.WriteLine("Text:{0}", text); 
    } 
} 

Répondre

4

Essayez la mise en œuvre d'une interface:

Exemple:

public interface IHasTwoMethods 
{ 
string MethodOne() 
string MethodTwo() 
} 

Mettre en oeuvre cette inteface sur vos classes:

class ClassOne : IHasTwoMethods 
class ClassTwo : IHasTwoMethods 

Ensuite, dans votre méthode générique faire comme ceci:

public static void WriteMessage<T>(T objectA) where T : IHasTwoMethods 
    { 
     var text = objectA.MethodTwo(); //Will work 
     Console.WriteLine("Text:{0}", text); 
    } 

Vous pouvez en savoir plus sur les interfaces ici: http://msdn.microsoft.com/en-us/library/87d83y5b.aspx

+1

1 Le concept le plus important est ici une contrainte de type générique (pas d'interface) mais la solution est correcte. – BradleyDotNET

1

Puisque vous êtes de passage dans un objet générique typé avec T, le compilateur ne sait pas quelle classe vous utilisez - pour tout ce qu'il sait, ce pourrait être un int ou un Application ou quoi que ce soit. Ce que vous voulez probablement est d'avoir ClassOne et ClassTwo hériter d'une autre classe qui a une classe abstraite MethodTwo que les deux implémenter. Quelque chose comme ...

abstract class SuperClass 
{ 
    public abstract string MethodOne(); 
} 

class ClassOne : SuperClass 
{ 
    public override string MethodOne() 
    { 
     return ("ClassOne"); 
    } 
} 

puis à Main:

public static void WriteMessage<T>(T objectA) where T : SuperClass 
{ 
    var text = objectA.MethodOne(); 
    Console.WriteLine("Text:{0}", text); 
} 

Lire sur l'héritage C# ici: http://msdn.microsoft.com/en-us/library/ms173149.aspx

+1

Techniquement cela ne fonctionnerait pas, puisque vous avez MethodOne comme méthode dans la classe abstraite, mais appelez MethodTwo. – BradleyDotNET

+0

Sloppy copier-coller de ma part. –

2

Cela ne compile pas car pour autant que le compilateur concerne objectA est juste un Object.

Pour que cela fonctionne, vous devez utiliser une contrainte de type générique :

public interface MyInterface 
{ 
    string MethodTwo(); 
} 

public class A : MyInterface 
{ 
    ... 
} 

public class B : MyInterface 
{ 
    ... 
} 

public static void WriteMessage<T>(T objectA) where T: MyInterface 
{ 
    var text = objectA.MethodTwo(); //Will Work! 
    Console.WriteLine("Text:{0}", text); 
} 

MSDN: Constraints on Type Parameters

+0

@elgonzo Yep, je pense que j'ai mal tapé cela au moins 3 ou 4 fois en écrivant ce post :( – BradleyDotNET

+0

Ne vous inquiétez pas, j'ai eu du plaisir à dire à voix haute "Method2 n'est pas la même que MethodTwo";) – elgonzo

+0

@elgonzo Je parie. Maintenant, je comprends pourquoi tout le monde nomme leurs fonctions "foo" et "bar" :) – BradleyDotNET

Questions connexes