在C ++中,这有效。
template<class T> void func(T t)
{ t.method(); }
如何在C#中实现呢?这是我尝试过的方法,但是不起作用。
void func<T>(T t)
{ t.method(); }
还是无法在C#中做到这一点?
答案 0 :(得分:3)
以下应该可以工作
public static class MyClass
{
public static void MyMethod<T>(T t) where T : class
{
t.ToString(); // Note: for this to work we need to KNOW the type which defines `method`.
}
}
以及此:
public class MyBase
{
void Method();
}
public static class MyClassForBase
{
public static void MyMethod<T>(T t) where T : MyBase
{
t.Method(); // Note: anything from MyBase is now available
}
}
最后但并非最不重要的是,您可以像这样使用后期绑定
public static class MyClassDynamic
{
public static void MyMethod(dynamic t)
{
t.Method(); // Note: if t doesn't have a `Method` defined, the code will crush-n-burn at runtime
}
}
答案 1 :(得分:1)
在带有通用参数的方法中,您只能在编译器知道将要在该参数上使用的方法上调用该方法。
在您的示例中:
void func<T>(T t)
{
t.method();
}
编译器不知道方法method
存在,因此将不起作用。
您可以使用constraints告诉编译器哪些方法可用。例如,如果方法是在接口上定义的,则可以使用where
子句来正确地约束它,如下所示:
pubic interface IClassWithMethod
{
void method();
}
void func<T>(T t) where T : IClassWithMethod
{
t.method();
}
答案 2 :(得分:0)
C#中的泛型与C ++中的模板不同。 C ++模板本质上是marcos,可在编译时根据其使用的类型来应用于代码。因此,如果您尝试在没有.method()
方法的类上使用模板,则它将在编译时失败。
C#泛型要求所有T
类型都必须定义该泛型方法使用的任何方法和属性。因此,如果您具有定义.method()
方法的基本类型或接口,则可以将泛型方法限制为该类型:
void func<T>(T t) where T:IHaveMethod
{ t.method(); }
只要IHaveMethod
接口定义了method()
,泛型函数就会编译。请注意,在您的特定示例中,通用方法没有用,因为您只需在接口类型上调用method
。
泛型更有用的地方是当您希望返回类型基于输入类型时:
T func<T>(T t) where T:IHaveMethod
{ t.method(); return t;}
现在,不仅会调用method
,而且返回类型也正是泛型参数的类型,而不仅仅是IHaveMethod
,这可能会限制您在不进行强制转换的情况下可以进行返回操作
最重要的是,不要像对待C ++模板那样考虑泛型。这是非常根本的区别,这将使您更难了解何时/应在何处使用泛型。