C# 为什么结果代码与声明泛型类的两种方式不同
如果之前有人问过,请道歉;我发现很难找到合适的搜索词 原因是:C# 为什么结果代码与声明泛型类的两种方式不同,c#,generics,C#,Generics,如果之前有人问过,请道歉;我发现很难找到合适的搜索词 原因是: public class IsUserAnonymousCondition<T> : WhenCondition<T> where T: RuleContext { protected override bool Execute( T ruleContext ) { ... } } public类IsUserAnonymousCondition:WhenConditi
public class IsUserAnonymousCondition<T> : WhenCondition<T> where T: RuleContext
{
protected override bool Execute( T ruleContext )
{
...
}
}
public类IsUserAnonymousCondition:WhenCondition where T:RuleContext
{
受保护的覆盖布尔执行(T规则上下文)
{
...
}
}
不同于:
public class IsUserAnonymousCondition : WhenCondition<RuleContext>
{
protected override bool Execute( RuleContext ruleContext )
{
...
}
}
public类IsUserAnonymousCondition:WhenCondition
{
受保护的覆盖布尔执行(RuleContext RuleContext)
{
...
}
}
或者更确切地说;这两个编译不是相同的吗?如果没有,为什么没有
它们都是编译的,因此都应该重写相同的基方法
public abstract class WhenCondition<T> : RuleCondition<T> where T : RuleContext
{
protected abstract bool Execute(T ruleContext);
}
公共抽象类WhenCondition:RuleCondition其中T:RuleContext
{
受保护的抽象bool-Execute(T-ruleContext);
}
它们不一样-尽管在您的案例中没有功能上的差异,因为T
仅用作输入
如果条件有一个将T用作输出的方法时,
公共抽象类WhenCondition:RuleCondition其中T:RuleContext
{
受保护的抽象bool-Execute(T-ruleContext);
受保护的抽象T GetContext();
}
现在,您的两个类将不同,因为在设计时,IsUserAnonymousCondition.GetContext()
的实际返回类型是未知的(编译器只知道它派生自RuleContext
),但IsUserAnonymousCondition.GetContext()
的返回类型是已知的。在这种情况下:
WhenCondition<T> where T: RuleContext
现在这并不重要,但想想这样做会有什么不同:
T GetSomething()
vs
第一个类的返回类型可以不同于第二个类。这两个类提供相同的接口,但一个类是泛型的,另一个是泛型的这一简单事实并不会导致一些显著的差异
要了解这两者的区别,最明显的方法是尝试使用反射从类名实例化它们:在第一种情况下,您必须按名称获取泛型类,创建一个表示泛型类型实例的类型,并使用RuleContext
作为其类型参数,然后才创建它的实例。在第二种情况下,仅一个名称就足以获得类型
一个更微妙的问题是,用两种不同类型实例化的IsUserAnonymousCondition
和IsUserAnonymousCondition
的类型会有所不同。这意味着您无法将不同的IsUserAnonymousCondition
对象放入非通用容器。更实际地说,它们在您的情况下不是同义词,因为:
class StrinctRuleContext : RuleContext {}
有一个子类。然后我们就可以
var aStrinctRuleContext = new StrinctRuleContext();
var aRulesContext = new RuleContext();
我可以从那里得到什么
new IsUserAnonymousCondition().Execute(aruleContext)
这是一个编译错误,即通用版本允许对其输入进行比非通用版本更严格的类型限制。ie我可以自由创建一个IsUserAnonymousCondition,但不能“处理”基本RulesContext类
通用版本还保留了添加更多通用限制的能力,如果它是更进一步的子类,即:
IsUserAnonymousConditionThatNeedsSomeExtraMojo : IsUserAnonymousCondition<T> where T : ISomeExtraMojo
IsUserAnonymousCondition需要满足Extramojo:IsUserAnonymousCondition其中T:ISomeExtraMojo
将类型实现为RuleContext的过程中,哪一个没有。实际上,第二个类与第一个类不同,不是泛型的。在您的示例中,这些类在运行时的行为可能相同,但您必须认识到泛型给您带来了许多编译时好处。您可以尝试使用最抽象的类型,甚至对象
使您的类型尽可能通用,但从API的角度来看,这是一种可怕的体验。还有引用和值类型的装箱/拆箱问题……这很有意义。我太专注于当前场景,以及这两个变体(在我看来)将如何编译成相同的东西。当然没有,我现在明白了:-)
class StrinctRuleContext : RuleContext {}
var aStrinctRuleContext = new StrinctRuleContext();
var aRulesContext = new RuleContext();
IsUserAnonymousConditionThatNeedsSomeExtraMojo : IsUserAnonymousCondition<T> where T : ISomeExtraMojo