您将如何在C#中进行专业化?
我会提出一个问题。你有一个模板类型,你不知道它是什么。但是你知道如果它是从XYZ
派生的,你想调用.alternativeFunc()
。一种很好的方法是调用一个专门的函数或类,让normalCall
返回.normalFunc()
,同时在任何派生类型的XYZ
上进行其他专门化,以调用.alternativeFunc()
。在C#中如何做到这一点?
发布于 2009-03-02 01:45:29
假设您谈论的是模板专门化,因为它可以使用C++模板来完成-这样的功能在C#中并不真正可用。这是因为C#泛型在编译期间不会被处理,而更多的是运行时的一个特性。
但是,您可以使用C# 3.0扩展方法来实现类似的效果。下面的示例展示了如何仅为MyClass<int>
类型添加扩展方法,这就像模板专门化一样。但是请注意,您不能使用它来隐藏该方法的默认实现,因为C#编译器总是首选标准方法而不是扩展方法:
class MyClass<T> {
public int Foo { get { return 10; } }
}
static class MyClassSpecialization {
public static int Bar(this MyClass<int> cls) {
return cls.Foo + 20;
}
}
现在你可以这样写了:
var cls = new MyClass<int>();
cls.Bar();
如果您希望在没有提供专门化的情况下使用该方法的默认情况,那么我相信编写一个通用的Bar
扩展方法应该可以做到这一点:
public static int Bar<T>(this MyClass<T> cls) {
return cls.Foo + 42;
}
发布于 2015-04-01 05:53:49
我也在寻找一种模式来模拟模板专门化。有一些方法在某些情况下可能会起作用。然而,这个案例呢?
static void Add<T>(T value1, T value2)
{
//add the 2 numeric values
}
可以使用语句选择操作,例如if (typeof(T) == typeof(int))
。但有一种更好的方法来模拟真实的模板专门化,只需一个虚拟函数调用的开销:
public interface IMath<T>
{
T Add(T value1, T value2);
}
public class Math<T> : IMath<T>
{
public static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();
//default implementation
T IMath<T>.Add(T value1, T value2)
{
throw new NotSupportedException();
}
}
class Math : IMath<int>, IMath<double>
{
public static Math P = new Math();
//specialized for int
int IMath<int>.Add(int value1, int value2)
{
return value1 + value2;
}
//specialized for double
double IMath<double>.Add(double value1, double value2)
{
return value1 + value2;
}
}
现在,我们可以编写代码,而不必事先知道类型:
static T Add<T>(T value1, T value2)
{
return Math<T>.P.Add(value1, value2);
}
private static void Main(string[] args)
{
var result1 = Add(1, 2);
var result2 = Add(1.5, 2.5);
return;
}
如果不仅应该为实现的类型调用专门化,而且还应该为派生类型调用专门化,则可以对接口使用In
参数。但是,在这种情况下,方法的返回类型不能再是泛型类型T
。
发布于 2018-03-02 23:56:47
我认为有一种方法可以通过.NET 4+使用动态解析来实现:
static class Converter<T>
{
public static string Convert(T data)
{
return Convert((dynamic)data);
}
private static string Convert(Int16 data) => $"Int16 {data}";
private static string Convert(UInt16 data) => $"UInt16 {data}";
private static string Convert(Int32 data) => $"Int32 {data}";
private static string Convert(UInt32 data) => $"UInt32 {data}";
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Converter<Int16>.Convert(-1));
Console.WriteLine(Converter<UInt16>.Convert(1));
Console.WriteLine(Converter<Int32>.Convert(-1));
Console.WriteLine(Converter<UInt32>.Convert(1));
}
}
输出:
Int16 -1
UInt16 1
Int32 -1
UInt32 1
这表明为不同的类型调用了不同的实现。
https://stackoverflow.com/questions/600978
复制相似问题