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);
}
}
它不编译,因为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