【发布时间】:2013-01-11 02:40:32
【问题描述】:
我有以下情况。
我的 Factory 类需要根据 CreateStrategy 函数的输入字符串参数创建适当的 Strategy 对象。
Strategy1、Strategy2 等都派生自一个通用的 StrategyBase 类。然而,每种策略都有不同的验证机制,它是工厂类的类型参数。但是,StrategyValidators 不是任何通用类型,并且具有不同的接口。
因此,在下面的代码中,我无法对 StrategyValidator 类型指定任何通用约束。
我是 C# 新手,因此不确定是否存在任何机制来克服这个设计问题。请推荐
public class Factory
{
//Create the appropriate Concrete Implementation class based on the type
public static StrategyBase CreateStrategy<StrategyValidator>(String Type)
{
StrategyBase EnumImp = null;
// WMI based implementation
if (Type == "Type1")
{
s = Strategy1<StrategyValidator>.Instance;
}
else if (Type = "Type2")
{
s = Strategy2<StrategyValidator>.Instance;
}
return s;
}
private StrategyBase s;
}
这是预期的用途
Factory f = new Factory();
f.CreateStrategy<WMIValidator>("WMI");
f.CreateStrategy<ABCDValidator>("ABCD");
其中WMIValidator 和ABCDValidator 是不相关的类型,但CreateStrategy 函数创建的实际类在层次结构中是相关的,例如有一个共同的基础StrategyBase
这里有一个示例代码来说明问题
namespace TestCSharp
{
public interface IStrategy
{
};
public interface S1 : IStrategy
{
void f1();
void f2();
};
public class S1Concrete : S1
{
public void f1() { }
public void f2() { }
}
public interface S2 : IStrategy
{
void f3();
void f4();
};
public class S2Concrete : S2
{
public void f3() { }
public void f4() { }
};
public interface ProductBase
{
};
class Product1<T> : ProductBase where T : S1
{
};
class Product2<T> : ProductBase where T : S2
{
};
public class Factory
{
public ProductBase Create<T>(String Type)
{
if (Type == "P1")
return new Product1<T>();
else if (Type == "P2")
return new Product2<T>();
}
};
class Program
{
static void Main(string[] args)
{
Factory f = new Factory();
ProductBase s = f.Create<S1Concrete>("Type1");
}
}
}
我得到的错误是
类型“T”不能用作泛型类型中的类型参数“T” 或方法“TestCSharp.Product1”。没有拳击转换或 类型参数从 'T' 到 'TestCSharp.S1' 的转换。
【问题讨论】:
-
我对你的意图有点困惑,你能添加一些你想如何使用工厂的代码吗?
-
我想传入与不同 Strategy 对象关联的不同验证类型。 CreateStrategy 只是帮助我用用户指定的验证类实例化适当的策略对象
-
而且由于策略使用完全不同的机制来实现相同的目标,因此它们的验证是唯一的,通常没有共性
-
我特别有兴趣看到使用代码,因为我不太清楚为什么你在这里有类级别的泛型而不是方法级别。顺便说一句,也许它们的共同点是它们都是一种策略?
-
@Chubsdad 我不明白。如果您可以编辑
ABCDValidator和WMIValidator,您不能简单地给它们一个共同的祖先类/接口,即使是空的,然后将其用作约束?
标签: c#