通用 class 的基础 class 约束指定 class 本身
Base class constraint on generic class specifying the class itself
昨天,我正在向我的朋友解释 C# 的泛型约束。在演示 where T : CLASSNAME
约束时,我想出了这样的东西:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
看到它编译时真的很惊讶。然而,经过一番思考,我认为从编译器的角度来看,它是完全合法的——UnusableClass<T>
与任何其他可以在此约束中使用的 class 一样多。
然而,这留下了几个问题:如何使用这个 class?是否可以
- 实例化它?
- 从中继承?
- 调用它的静态方法
int method
?
而且,如果是,怎么做?
如果这些 中的任何一个是 可能的,那么 T
的类型是什么?
If any of these is possible, what would the type of T be?
它们都是可能的,您将决定 T
的类型。例如,假设有一种类型继承自 UnusableClass<T>
class Foo : UnusableClass<Foo> { }
现在可以实例化UnusableClass<Foo>
因为Foo
满足约束:
UnusableClass<Foo> f = new UnusableClass<Foo>();
然后 T
的类型变为 Foo
如果您尝试调用 method
则需要传递 Foo
.
的实例
嗯。
public class Implementation : UnusableClass<Implementation>
{
}
完全有效,因此
var unusable = new UnusableClass<Implementation>();
和
UnusableClass<Implementation>.method(new Implementation());
有效。
所以,是的,它可以通过提供继承类型作为类型参数来实例化,类似于调用静态方法。例如,它对于树状结构很有用,在这种结构中,您想要一般地指定节点具有的子节点的类型,同时它本身是相同的类型。
这种方法广泛用于树和其他类似图的结构。在这里你对编译器说,T 有 API 个 UnusableClass。也就是说,您可以按如下方式实现 TreeNode:
public class TreeNode<T>
where T:TreeNode<T>
{
public T This { get { return this as T;} }
public T Parent { get; set; }
public List<T> Childrens { get; set; }
public virtual void AddChild(T child)
{
Childrens.Add(child);
child.Parent = This;
}
public virtual void SetParent(T parent)
{
parent.Childrens.Add(This);
Parent = parent;
}
}
然后像这样使用它:
public class BinaryTree:TreeNode<BinaryTree>
{
}
昨天,我正在向我的朋友解释 C# 的泛型约束。在演示 where T : CLASSNAME
约束时,我想出了这样的东西:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
看到它编译时真的很惊讶。然而,经过一番思考,我认为从编译器的角度来看,它是完全合法的——UnusableClass<T>
与任何其他可以在此约束中使用的 class 一样多。
然而,这留下了几个问题:如何使用这个 class?是否可以
- 实例化它?
- 从中继承?
- 调用它的静态方法
int method
?
而且,如果是,怎么做?
如果这些 中的任何一个是 可能的,那么 T
的类型是什么?
If any of these is possible, what would the type of T be?
它们都是可能的,您将决定 T
的类型。例如,假设有一种类型继承自 UnusableClass<T>
class Foo : UnusableClass<Foo> { }
现在可以实例化UnusableClass<Foo>
因为Foo
满足约束:
UnusableClass<Foo> f = new UnusableClass<Foo>();
然后 T
的类型变为 Foo
如果您尝试调用 method
则需要传递 Foo
.
嗯。
public class Implementation : UnusableClass<Implementation>
{
}
完全有效,因此
var unusable = new UnusableClass<Implementation>();
和
UnusableClass<Implementation>.method(new Implementation());
有效。
所以,是的,它可以通过提供继承类型作为类型参数来实例化,类似于调用静态方法。例如,它对于树状结构很有用,在这种结构中,您想要一般地指定节点具有的子节点的类型,同时它本身是相同的类型。
这种方法广泛用于树和其他类似图的结构。在这里你对编译器说,T 有 API 个 UnusableClass。也就是说,您可以按如下方式实现 TreeNode:
public class TreeNode<T>
where T:TreeNode<T>
{
public T This { get { return this as T;} }
public T Parent { get; set; }
public List<T> Childrens { get; set; }
public virtual void AddChild(T child)
{
Childrens.Add(child);
child.Parent = This;
}
public virtual void SetParent(T parent)
{
parent.Childrens.Add(This);
Parent = parent;
}
}
然后像这样使用它:
public class BinaryTree:TreeNode<BinaryTree>
{
}