C#中的模板函数 - 返回类型是什么?

24

似乎C#不支持类似于C++的模板。例如:

template <class myType>
myType GetMax (myType a, myType b) {
 return (a>b?a:b);
}
我希望我的函数的返回类型基于其参数,如何在C#中实现此目标?如何在C#中使用模板?
编辑:我可以使用object和getType来实现几乎相同的目的吗?

我不认为你可以使用GetType来完成同样的事情。而且,除非你希望调用者在各个地方进行强制转换,否则你不希望API返回对象。 - Jon Skeet
7个回答

43

C++中最接近模板的语法在C#中被称为泛型,但它们并不是非常相似。特别地,你不能在泛型类型值之间使用像>这样的运算符,因为编译器不知道它们(也无法基于运算符约束类型)。另一方面,你可以写:

public T GetMax<T>(T lhs, T rhs)
{
    return Comparer<T>.Default.Compare(lhs, rhs) > 0 ? lhs : rhs;
}

或者

public T GetMax<T>(T lhs, T rhs) where T : IComparable<T>
{
    return lhs.CompareTo(rhs) > 0 ? lhs : rhs;
}

请注意,第一个选项是null安全的,而第二个选项则不是。
泛型的完整描述远超出了Stack Overflow答案的范围;请查阅MSDN或参考您喜欢的C#书籍获取更多信息。

2
我听说《深入浅出C#》有一些很好的泛型解释 :) - SWeko
1
给出的函数只是一个示例,那么除了比较之外的其他函数呢? - SMUsamaShah
@Life2HO:好的,你需要什么功能?是在接口中指定的实例方法吗?如果是这样,那就没问题了。 - Jon Skeet

9

C#中的泛型并不像C++中的模板那样强大。您想要实现的内容在C#中无法实现。

针对您的情况,可以使用一个hack/解决方法:

public T GetMax<T>(T a, T b) where T: IComparable {
    if(a.CompareTo(b) > 0) {
        return a;
    }
    return b;
}

给出的函数只是一个示例,那么除了比较之外的其他函数呢? - SMUsamaShah
1
@LifeH2O:这取决于它是否在接口中指定。如果是的话,你可以限制泛型类型实现该接口(或从给定的基类派生等)。 - Jon Skeet
1
作为一名C++开发人员,您可能会对C#的泛型感到失望。但是在许多情况下它们仍然非常有用,并值得学习。 - Matt Greer

5
您的代码将变成这样:
public T GetMax<T>(T a, T b) where T : IComparable<T>
{
    return a.CompareTo(b) > 0 ? a : b;
}

3

3

您需要查看泛型。语法:

public T GetMax<T>(T a, T b) {
    return (a>b?a:b);
}

更新:因为有些评论,我只想提供一个非常简要的概述。是的,我猜它不能正确编译或执行。但这是这个想法的基本样子。您将在此主题上找到更完整的回复-同时。

执行语法:

int a = 5;
int b = 10;
int result = GetMax(a, b);

希望这能帮到您,
祝好, Thomas

1
我本来也想这么说,但是由于这行代码 'return (a>b?a:b);' 无法编译,他需要一个接口约束或其他什么东西... - µBio
3
编译器不知道T是什么,因此您不能以这种方式比较a和b。如果类型T不支持比较呢? - Matt Greer

1

泛型!

class MyClass<T> where T : IEnumerable (any parent class here!)
{
   T myGeneric {get; set;}
}

-1
你的意思是像这样的东西。
   public static IEnumerable<TResult> SelectIfNotNull<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
   {
       if (source == null) return null;
       return source.Select(selector);
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接