是否可以在C#中为泛型制作"此类型"?

XOR*_*XOR 5 .net c# generics

一种理论问题.很长一段时间,如果你没有理论的心情,请随意跳过.

想象一下,你有两个类,一个继承自另一个.基类是通用的,并且有一个方法,在闭合类型中必须返回此闭合类型的某个实例.

像这样(注意文字中的???):

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<...>.

如果你很容易可以避免这种情况,因为它变得如此复杂 - 但我确实认为这是一个有用的模式.


Ree*_*sey 5

在这种情况下,您通常只想引用基类:

public class Adapter<T> { 
   public virtual Adapter<T> DoSomething();
Run Code Online (Sandbox Code Playgroud)

试图做你正在完成的事情违反了Liskov替换委托人.