一种理论问题.很长一段时间,如果你没有理论的心情,请随意跳过.
想象一下,你有两个类,一个继承自另一个.基类是通用的,并且有一个方法,在闭合类型中必须返回此闭合类型的某个实例.
像这样(注意文字中的???):
public class Adapter<T>
{
public virtual ??? DoSomething()
{
...
}
}
public class AdaptedString : Adapter<String>
{
public override AdaptedString DoSomething()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我不能这样做,因为没有办法引用将从泛型类型派生的闭合类型.(对不起破解语言,只是不知道如何表达它.)没有设置关键字???
来指定此方法将返回将从此泛型类型派生的类型实例.
相反,我可以使用显式将类型名称传递给通用基础的变通方法.但它看起来多余.
public class Adapter<TThis,T>
{
public virtual TThis DoSomething()
{
...
}
}
public class AdaptedString : Adapter<AdaptedString,String>
{
public override AdaptedString DoSomething()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
如果在基类中我需要访问TThis
实例的成员,我必须添加一个约束.这一次看起来很难看 - 请注意约束:
public class Adapter<TThis,T>
where TThis : Adapter<TThis, T>
{
protected int _field;
...
public bool Compare( TThis obj )
{
return _field == obj._field;
}
}
public class AdaptedString : Adapter<AdaptedString,String>
{
...
}
Run Code Online (Sandbox Code Playgroud)
是的,它一切正常,但如果我可以简单地使用一些关键字而不是???
第一个代码片段,它看起来会更好.像" thistype " 这样的东西.
您认为它如何运作?它有用吗?或者这可能只是愚蠢的?
Jon*_*eet 13
没有任何东西可以使这种模式更容易,事实上这种模式无论如何都不是防弹 - 因为你可以:
class TypeA : Adapter<TypeA, string>
class TypeB : Adapter<TypeA, string> // Bug!
Run Code Online (Sandbox Code Playgroud)
这里的第二行完全合法 - TypeA
是类型参数的有效TThis
类型参数,即使它不是我们想要的.基本上,类型系统不允许我们表达"T必须是这种类型"的概念.
然而,我不同意那些说这是一种坏的或无用的模式的人.我发现它在Protocol Buffers中很有用(如果复杂的话)- 没有它会更糟糕.例如:
Foo foo = new Foo.Builder { Name="Jon" }.Build();
Run Code Online (Sandbox Code Playgroud)
如果Foo.Build()
没有强类型返回Foo
,即使Build
指定了方法,也无法工作IBuilder<...>
.
如果你很容易就可以避免这种情况,因为它变得如此复杂 - 但我确实认为这是一个有用的模式.
在这种情况下,您通常只想引用基类:
public class Adapter<T> {
public virtual Adapter<T> DoSomething();
Run Code Online (Sandbox Code Playgroud)
试图做你正在完成的事情违反了Liskov替换委托人.
归档时间: |
|
查看次数: |
2503 次 |
最近记录: |