C ++模板与带有各种参数的C#通用方法

时间:2018-12-18 00:54:14

标签: c# generics

在C ++中,这有效。

template<class T> void func(T t)
{ t.method(); }

如何在C#中实现呢?这是我尝试过的方法,但是不起作用。

void func<T>(T t)
{ t.method(); }

还是无法在C#中做到这一点?

3 个答案:

答案 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 ++模板那样考虑泛型。这是非常根本的区别,这将使您更难了解何时/应在何处使用泛型。