【发布时间】:2016-03-16 22:33:28
【问题描述】:
我正在尝试使用基于 this answer 的 C# 泛型和策略模式来实现类似 c++ 的模板
这是模式的示例:
interface ISomePolicy<T,U>
{
void _doSomething(U u);
}
class MyClass<T,U>:
ISomePolicy<int, double>,
ISomePolicy<int, int>
{
internal T myElement {get;set;}
public MyClass(T Element) {
myElement = Element;
}
void ISomePolicy<int, double>._doSomething(double u)
{
Console.WriteLine("this is int, double");
}
void ISomePolicy<int, int>._doSomething(int u)
{
Console.WriteLine("this is int, int");
}
}
static class MyClassExtension
{
//What I want to do
public static void doSomething<P, T, U>(this P oTh, U u) where P : MyClass<T, U>, ISomePolicy<T, U>
{
oTh._doSomething(u);
}
}
我的预期行为是这样的:
MyClass<int, double> oClass = new MyClass<int, double>(3);
oClass.doSomething(0.5); //This works
oClass.doSomething(1); //This works
oClass.doSomething("This should fail"); //Breaks at compile time
MyClass<string, double> oClass1 = new MyClass<string, double>("sadfsd"); //Not implemented, wasn't able to prevent the construction.
oClass1.doSomething(0.4); //Breaks at compile time
但到目前为止,我无法让 .net 接受 Generic Extension with less arguments than parameters
我可以显式调用接口,这太冗长了,违背了所有这些的目的。
oClass.doSomething < MyClass<int, double>,int,double>(0.5);
我想用一个包装器来解决这个问题:
static class MyClassExtension{
private static void wrappedDoSomething<P, T, U>(this P oTh, U u)
where P : MyClass<T, U>, ISomePolicy<T, U>
{
oTh._doSomething(u);
}
public static void doSomething<T, U>(this MyClass<T, U> oTh, U u)
{
oTh.wrappedDoSomething<MyClass<T, U>, T, U>(u);
}
}
但是包装器无法解析被包装函数的两种类型,失败:
错误 1 类型 'MyClass' 不能用作类型参数 'P' 在泛型类型或方法中 'MyClassExtension.wrappedDoSomething(P, U)'。没有 从 'MyClass' 到的隐式引用转换 'ISomePolicy'
感谢任何解决参数问题或重新设计所有这些问题的见解。
对于上下文,这将用于包装 I/O 转换器。 T 在我的例子中是目标 I/O 格式,U 是我的框架使用的数据的对象表示。
我知道这可以通过委托或接口轻松实现,但目标是框架用户可以轻松实例化所需的翻译,如果实现不存在,则可以轻松地将其添加到通用接口.
编辑:从另一个泛型方法/类中解析一个泛型方法似乎都不适用于单声道。
【问题讨论】:
-
为什么需要 T 参数?
-
在编译时检查
ISomePolicy<T, U>是否由MyClass实现(参见MyClassExtension)
标签: c# generics extension-methods implicit-conversion template-specialization