简体   繁体   English

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

[英]Calling methods and properties of reference types in generic classes

While there are plenty of example on generics using primitve types like int ans string I couldn't really find one using proper classes. 尽管有很多使用primitve类型的泛型示例(例如int ans字符串),但使用合适的类却找不到真正的泛型。 Here is the scenario 这是场景

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

            mt.GetValueFromType();

            Console.ReadKey();
        }
    }

This is the generic class 这是通用类

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?


    }
}

One of the types that will be sent in to the generic class as 将作为以下类型发送到泛型类的一种类型

public class TClass
{

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

Can this even be done in C# or do I need to refer to an interface of TClass with the new MyClass<T>().GetValueFromType() method ? 甚至可以在C#中完成此操作,还是需要使用new MyClass<T>().GetValueFromType()方法引用TClass的接口?

If I have to use interface then why use generics at all? 如果我必须使用接口,那为什么还要使用泛型呢?

All the compiler can infer is that generic parameter T is of type Object so only the methods and properties for System.Object will be available. 编译器可以推断出,通用参数T是Object类型的,因此只有System.Object的方法和属性才可用。 In order to get beyond that, you need to tell the compiler that T is expected to be derived from a base type, or implements specific interfaces. 为了超越此范围,您需要告诉编译器T应该是从基本类型派生的,或实现特定的接口。 This is called a generic constraint: 这称为通用约束:

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

So in this example any class derived from BaseClass can be used for the generic parameter T. You can also do the same thing with an interface. 因此,在此示例中,从BaseClass派生的任何类都可以用于通用参数T。您也可以对接口执行相同的操作。 But in that case it would be more along the lines of that T implements the constrained interface. 但是在那种情况下,T更可能实现受约束的接口。 Usually the interface route is much more flexible since c# does not allow multiple inheritance. 通常,接口路由更加灵活,因为c#不允许多重继承。

You can use generic constrains what I think will accomplish what your after: 您可以使用通用约束来约束您完成的任务:

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

I'd create an abstract base class, say MyBase that defines the method MyTypeMethod() : 我将创建一个抽象基类,比如说MyBase ,它定义了方法MyTypeMethod()

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

All the classes you want to use in the generic class would inherit from this. 您要在泛型类中使用的所有类都将继承自此。 Override and implement MyTypeMethod() 重写并实现MyTypeMethod()

Modify your generic class: 修改您的通用类:

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

    }
}

You could also use an interface as gleng suggested. 您还可以使用gleng建议的界面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM