C#:传递泛型对象

本文关键字:泛型 对象 | 更新日期: 2023-09-27 18:27:33

我想要一个通用的打印函数。。。打印通用(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);
    }
}

C#:传递泛型对象

它不编译,因为t可以是任何东西,并且不是所有东西都有myvar字段。

您可以使myvar成为ITest:上的属性

public ITest
{
    string myvar{get;}
}

并将其作为属性在类上实现:

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

然后对你的方法施加一个通用的约束:

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

但在这种情况下,老实说,你最好通过ITest:

public void PrintGeneric(ITest test)
{
    Console.WriteLine("Generic : " + test.myvar);
}

您至少缺少了一些东西:

  • 除非使用反射,否则类型参数需要在编译时已知,因此不能使用

    PrintGeneric<test2.GetType()>
    

    尽管在这种情况下,你无论如何都不需要

  • PrintGeneric目前对T一无所知,因此编译器找不到名为T 的成员

选项:

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

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

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

您必须提供有关泛型类型T的更多信息。在您当前的PrintGeneric方法中,T可能是一个string,它没有var成员。

您可能希望将var更改为属性,而不是字段

public interface ITest
{
    string var { get; }
}

并在CCD_ 18方法的基础上增加了一个约束条件CCD_。

在泛型方法中,T只是一个类型的占位符。然而,编译器本身并不知道运行时使用的具体类型,因此不能假设它们将具有var成员。

避免这种情况的通常方法是在方法声明中添加一个泛型类型约束,以确保所使用的类型实现特定的接口(在您的情况下,它可能是ITest):

public void PrintGeneric<T>(T test) where T : ITest

然后,该接口的成员将在方法内部直接可用。但是,您的ITest当前是空的,您需要在那里声明公共内容,以便在方法中使用它。

尝试

public void PrintGeneric<T>(T test) where T: ITest
{
    Console.WriteLine("Generic : " + test.@var);
}

正如@Ash Burlaczenko所说,如果你真的想用带有@符号的前缀来转义关键字

,你就不能用关键字来命名变量

您需要在接口中定义一些东西,例如:

public interface ITest
{
    string Name { get; }
}

在您的类中实现ITest

public class MyClass1 : ITest
{
    public string Name { get { return "Test1"; } }
}
public class MyClass2 : ITest
{
    public string Name { get { return "Test2"; } }
}

然后将您的通用Print函数限制为ITest:

public void Print<T>(T test) where T : ITest
{
}

不能使用泛型访问var

试试之类的东西

Console.WriteLine("Generic : {0}", test);

并覆盖ToString方法[1]

[1]http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx