Pao*_*sco 10 c# generics constraints
我想在基类泛型类中创建一个方法来返回派生对象的专用集合并对它们执行一些操作,如下例所示:
using System;
using System.Collections.Generic;
namespace test {
class Base<T> {
public static List<T> DoSomething() {
List<T> objects = new List<T>();
// fill the list somehow...
foreach (T t in objects) {
if (t.DoSomeTest()) { // error !!!
// ...
}
}
return objects;
}
public virtual bool DoSomeTest() {
return true;
}
}
class Derived : Base<Derived> {
public override bool DoSomeTest() {
// return a random bool value
return (0 == new Random().Next() % 2);
}
}
class Program {
static void Main(string[] args) {
List<Derived> list = Derived.DoSomething();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是要做这样的事情,我需要指定一个约束
class Base<T> where T : Base {
}
Run Code Online (Sandbox Code Playgroud)
有可能以某种方式指定这样的约束吗?
Meh*_*ari 22
这可能对你有用:
class Base<T> where T : Base<T>
Run Code Online (Sandbox Code Playgroud)
您不能限制T为开放的泛型类型.如果您需要限制T到Base<whatever>,你需要构建这样的:
abstract class Base { }
class Base<T> : Base where T : Base { ... }
Run Code Online (Sandbox Code Playgroud)
我使用以下内容创建不是链接列表,而是创建一个generecic链接树.它非常好用.
public class Tree<T> where T : Tree<T>
{
T parent;
List<T> children;
public Tree(T parent)
{
this.parent = parent;
this.children = new List<T>();
if( parent!=null ) { parent.children.Add(this as T); }
}
public bool IsRoot { get { return parent == null; } }
public bool IsLeaf { get { return children.Count == 0; } }
}
Run Code Online (Sandbox Code Playgroud)
力学的示例用法(坐标系层次结构)
class Coord3 : Tree<Coord3>
{
Vector3 position;
Matrix3 rotation;
private Coord3() : this(Vector3.Zero, Matrix3.Identity) { }
private Coord3(Vector3 position, Matrix3 rotation) : base(null)
{
this.position = position;
this.rotation = rotation;
}
public Coord3(Coord3 parent, Vector3 position, Matrix3 rotation)
: base(parent)
{
this.position = position;
this.rotation = rotation;
}
public static readonly Coord3 World = new Coord3();
public Coord3 ToGlobalCoordinate()
{
if( IsRoot )
{
return this;
} else {
Coord3 base_cs = parent.ToGlobalCoordinate();
Vector3 global_pos =
base_cs.position + base_cs.rotation * this.position;
Matrix3 global_rot = base_cs.rotation * this.rotation;
return new Coord3(global_pos, global_ori );
}
}
}
Run Code Online (Sandbox Code Playgroud)
诀窍是用null父对象初始化根对象.记住,你不能这样做Coord3() : base(this) { }.