在泛型类中调用引用类型的方法和属性

时间:2014-04-11 15:23:50

标签: c# .net generics

虽然有很多关于使用诸如int和string这样的原始类型的泛型的例子,但我真的找不到使用适当类的一个。这是方案

    //main program
    class Program
    {
        static void Main(string[] args)
        {
            MyClass<TClass> mt = new MyClass<TClass>();

            mt.GetValueFromType();

            Console.ReadKey();
        }
    }

这是通用类

public class MyClass<T>  
{
    public void GetValueFromType()
    {
        Console.WriteLine("Genric method called");

         //Need to call the method MyTypeMethod() from the reference type sent in here.                
         //How?


    }
}

将作为

发送到通用类的其中一种类型
public class TClass
{

    public void MyTypeMethod()
    {
        Console.WriteLine("Type method called");
    }
}

这甚至可以在C#中完成,还是需要使用new MyClass<T>().GetValueFromType()方法引用TClass的接口?

如果我必须使用界面那么为什么要使用泛型?

3 个答案:

答案 0 :(得分:1)

所有编译器都可以推断出泛型参数T的类型是Object,因此只有System.Object的方法和属性可用。为了超越这个范围,您需要告诉编译器,期望T是从基类型派生的,或者实现特定的接口。这称为通用约束:

public abstract class BaseClass
{

  public virtual void MyTypeMethod()
  {     
  }

}


 public class TClass : BaseClass
 {

    public override void MyTypeMethod()
    {
       Console.WriteLine("Type method called");
    }

 }



public class MyClass<T> where T: BaseClass
{
    public void GetValueFromType(T value)
    {
        Console.WriteLine("Genric method called");
        value.MyTypeMethod();
    }
}

因此,在此示例中,从BaseClass派生的任何类都可以用于泛型参数T.您也可以使用接口执行相同的操作。但在这种情况下,更多的是T实现受约束的接口。通常,接口路由更灵活,因为c#不允许多重继承。

答案 1 :(得分:0)

您可以使用generic constrains我认为可以实现您的目标:

public class MyClass<T> where T: TClass
{
    public void GetValueFromType(T value)
    {
        Console.WriteLine("Genric method called");
        value.MyTypeMethod();
    }
}

答案 2 :(得分:0)

我创建了一个抽象基类,比如MyBase定义方法MyTypeMethod()

public abstract class MyBase
{
    public virtual void MyTypeMethod() { }
}

您要在泛型类中使用的所有类都将从此继承。覆盖并实施MyTypeMethod()

修改您的通用类:

public class MyClass<T> where T : MyBase
{
    public void GetValueFromType()
    {
        T.MyTypeMethod();        
        Console.WriteLine("Generic method called");

    }
}

您也可以使用gleng建议的界面。