c#泛型基类方法返回派生类的类型

时间:2018-01-18 03:26:43

标签: c# generics

我想要一个基类方法来返回派生类的类型。 根据{{​​3}}

基类

public class BaseClass<T>
{
}

扩展

public static class ExtensionMethods
{
   public static U Project<U, T>(this U node)
     where U : BaseClass<T>
  {
     // do something
     return node;
  }
}

儿童班

public class ChildClass: BaseClass<string>
{
}

使用

var child= new ChildClass();
var projected = child.Project(); // error: can't infer type T
var projected = child.Project<ChildClass, string>(); // ok

问题:  一个解决方案是Can a Base Class Method return the type of the derived class? ,但是从子类继承的类不起作用。  如何在不指定T的情况下使用方法?

1 个答案:

答案 0 :(得分:0)

答案是你需要提供所有管道来手动克隆对象,让编译器决定正确的过载。

public interface ICSGNode<T> where T:ICSGNode<T>
{
    T Clone();
    void Invert();
}
public class NodeList<T> : Collection<T>
    where T : ICSGNode<T> 

{
    public NodeList(params T[] items) : base(items) { }
    public static implicit operator NodeList<T>(T[] array) { return new NodeList<T>(array); }

    public T[] Clone() { return this.Select((n) => n.Clone()).ToArray(); }
}

public class PolygonNode : ICSGNode<PolygonNode>, ICloneable
{
    public PolygonNode()
    {
        // create a unique object
    }
    public PolygonNode(PolygonNode other)
    {
        // create a copy
    }

    public void Invert()
    {
        throw new NotImplementedException();
    }
    public PolygonNode Clone() { return new PolygonNode(this); }
    object ICloneable.Clone() { return Clone(); }

}

public class PolygonList : NodeList<PolygonNode>, ICloneable
{
    public PolygonList(params PolygonNode[] items) : base(items) { }
    public static implicit operator PolygonList(PolygonNode[] array) { return new PolygonList(array); }

    public new PolygonList Clone() { return new PolygonList(base.Clone()); }
    object ICloneable.Clone() { return Clone(); }
}
class Program
{
    static void Main(string[] args)
    {
        var list = new PolygonList
        {
            new PolygonNode(),
            new PolygonNode(),
            new PolygonNode(),
        };
        var clone = list.Clone();
        // clone is of `PolygonList` type
    }
}

使用的技巧:

  • 仅将ICloneable接口应用于派生类。
  • 使用强类型object方法覆盖返回Clone()的默认行为。
  • 实现仅在构造函数中复制对象属性的复制构造函数。
  • 最后,避免从任何基础Clone()方法返回具体或通用集合类型。返回一个数组,让派生类程序集成为项目数组中的强类型克隆。