C#:传递通用对象

use*_*895 17 c# generics methods

我希望有一个通用的打印功能... PrintGeneric(T)......在下面的例子中,我缺少什么?

一如既往,感谢您的帮助/见解......

public interface ITest
{}

public class MyClass1 : ITest
{
    public string myvar = "hello 1";
}

public class MyClass2 : ITest
{
    public string myvar = "hello 2";
}

class DoSomethingClass
{

    static void Main()
    {
        MyClass1 test1 = new MyClass1();
        MyClass2 test2 = new MyClass2();

        Console.WriteLine(test1.myvar);
        Console.WriteLine(test2.myvar);             
        Console.WriteLine(test1.GetType());

        PrintGeneric(test1);
        PrintGeneric<test2.GetType()>(test2);
    }

    // following doesn't compile
    public void PrintGeneric<T>(T test)
    {
        Console.WriteLine("Generic : " + test.myvar);
    }
}
Run Code Online (Sandbox Code Playgroud)

jon*_*ten 25

它没有编译,因为T可以是任何东西,并不是所有东西都有该myvar字段.

您可以创建myvar一个属性ITest:

public ITest
{
    string myvar{get;}
}
Run Code Online (Sandbox Code Playgroud)

并在类作为属性实现它:

public class MyClass1 : ITest
{
    public string myvar{ get { return "hello 1"; } }
}
Run Code Online (Sandbox Code Playgroud)

然后对您的方法设置一个通用约束:

public void PrintGeneric<T>(T test) where T : ITest
{
    Console.WriteLine("Generic : " + test.myvar);
}
Run Code Online (Sandbox Code Playgroud)

但在这种情况下说实话,你最好只是传递一个ITest:

public void PrintGeneric(ITest test)
{
    Console.WriteLine("Generic : " + test.myvar);
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 7

你至少缺少一些东西:

  • 除非您使用反射,否则需要在编译时知道类型参数,因此您无法使用

    PrintGeneric<test2.GetType()>
    
    Run Code Online (Sandbox Code Playgroud)

    ......虽然在这种情况下你无论如何都不需要

  • PrintGeneric目前不知道任何事情T,所以编译器找不到一个叫做的成员T

选项:

  • ITest接口中放置一个属性,并更改PrintGeneric为约束T:

    public void PrintGeneric<T>(T test) where T : ITest
    {
        Console.WriteLine("Generic : " + test.PropertyFromInterface);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • ITest接口中放置一个属性并完全删除泛型:

    public void PrintGeneric(ITest test)
    {
        Console.WriteLine("Property : " + test.PropertyFromInterface);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您使用的是C#4,请使用动态类型而不是泛型

  • @SteveHaigh:Doh,这就是我在同一时间打电话和通话的原因.固定,谢谢. (2认同)