C# 基于扩展方法的模板专门化
在C#中,我希望泛型类的一个方法以不同的方式运行,使用类似于 我从C#中看到,使用扩展可能会出现这样的情况,但我的代码没有按预期运行:我希望C# 基于扩展方法的模板专门化,c#,C#,在C#中,我希望泛型类的一个方法以不同的方式运行,使用类似于 我从C#中看到,使用扩展可能会出现这样的情况,但我的代码没有按预期运行:我希望thing::Method()有一个行为,而不是时有另一个行为 我有 using System; public interface IThing { void Method(); } public class Thing<T> : IThing { public void Method() { thi
thing::Method()
有一个行为,而
不是
时有另一个行为
我有
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();
}
}
使用系统;
公共接口
{
void方法();
}
公共类的东西:我喜欢
{
公开作废法()
{
这个。专门化();
}
}
公共静态类ThingExtensions
{
公共静态无效专门化(这个东西是cls)
{
Console.WriteLine(“事物专业化”);
返回;
}
公共静态无效专门化(这个东西是cls)
{
Console.WriteLine(“事物专业化”);
返回;
}
}
公共课程
{
公共静态void Main()
{
var t=新事物();
t、 方法();
t、 专门化();
var i=新事物();
i、 方法();
i、 专门化();
}
}
但这是一种输出
Thing<T> specialization
Thing<T> specialization
Thing<T> specialization
Thing<int> specialization
事物专门化
事物专门化
事物专门化
事物专门化
而不是
Thing<T> specialization
Thing<T> specialization
Thing<int> specialization
Thing<int> specialization
事物专门化
事物专门化
事物专门化
事物专门化
“为什么不直接调用专门化
而不是方法
?”这一显而易见的问题有望通过我的接口类的加入得到回答——我正在尝试适应它的框架
我可以看出
专业化
与专业化
是匹配的,但我很惊讶后者没有被视为更好的匹配 不幸的是,当您调用Method()
时,它作为Thing
运行,而不知道它是Thing
。您可以使用反射来发现这一点,或者(更好的主意):
if(Thing x的这个实例)
x、 专业化();
其他的
这就是专业化;
或者,您可以将
Method()
声明为virtual
并使用override void Method(){…}
调用this.Specialization()代码>在编译包含的方法时解析。在这一点上,T
是任何东西
<>一些通用支持语言(如C++)在所有类型参数(或C++的情况下,所有模板参数:C++模板参数不限于类型)时,尽可能晚地解决泛型方法的实现。
但C#没有采取这种做法。这确实有使编译模型更简单的优点,但它的功能不太强大
(就我个人而言,我希望能够明确地专门化,包括部分专门化,但我也认识到这对在.NET中解决类型的方式有挑战。)如果您唯一关心的是类型int,为什么不使用类型的一种专门化方法并在执行逻辑之前检查类型?泛型不是模板。不管怎么说,你所问的听起来像是特质,而不是模板专业化。干净的溶液是用C#8制成的。我在编译时发布了一个重载解析的例子。当编译Method
时,它必须携带什么类型的信息,因此它将选择哪个专门化重载?在traits问题中显示了如何在没有官方支持的情况下使用“traits”——不同的traits必须使用针对不同接口的扩展方法来实现,每个“特征”一个。它们也必须通过该接口调用
if(this instanceof Thing<int> x)
x.Specialisation();
else
this.Specialisation();