在C#中,我想让我的通用类的方法以类似于explicit template specialization
的方式以不同的方式运行我从a related post看到,使用扩展名在C#中可能发生这种情况,但是我的代码无法正常工作:我想要Thing<int>::Method()
的一种行为,而当{{1 }}是<T>
以外的任何东西。
我有
<int>
但这输出
using System;
public interface IThing
{
void Method();
}
public class Thing<T> : IThing
{
public void Method()
{
this.Specialization<T>();
}
}
public static class ThingExtensions
{
public static void Specialization<T>(this Thing<T> cls)
{
Console.WriteLine("Thing<T> specialization");
return;
}
public static void Specialization(this Thing<int> cls)
{
Console.WriteLine("Thing<int> specialization");
return;
}
}
public class Program
{
public static void Main()
{
var t = new Thing<float>();
t.Method();
t.Specialization();
var i = new Thing<int>();
i.Method();
i.Specialization();
}
}
而不是
Thing<T> specialization
Thing<T> specialization
Thing<T> specialization
Thing<int> specialization
一个显而易见的问题:“为什么不只叫Thing<T> specialization
Thing<T> specialization
Thing<int> specialization
Thing<int> specialization
而不叫Specialization<T>
?”希望通过包含接口类来解决-我正试图适应其框架。
我可以看到Method
是Specialization<T>
的匹配项,但令我惊讶的是后者没有被视为更好的匹配项!
答案 0 :(得分:2)
不幸的是,当您调用Method()
时,它以Thing<T>
的身份运行,而不知道它是Thing<int>
。您可以使用反射来找出答案,或者(更好的主意):
if(this instanceof Thing<int> x)
x.Specialisation();
else
this.Specialisation();
或者,您可以将Method()
声明为virtual
并使用IntThing : Thing<int>
创建override void Method(){...}
答案 1 :(得分:1)
编译包含方法时,对this.Specialization<T>();
的调用已解决。那时T
就是一切。
某些具有通用支持的语言(例如C ++)在所有类型参数(或在C ++情况下,所有模板参数:在C ++模板参数中不限于类型)时,都尽可能晚地解决了通用方法的实现。>
但是C#不采用这种方法。这样做确实具有使编译模型更简单的优点,但是功能却不那么强大。
(我个人希望具有显式专业化的能力,包括部分专业化,但是我也认识到这对.NET中解析类型的方式带来了挑战。)