【问题标题】:Getting correct subclass method from generic superclass definition从通用超类定义中获取正确的子类方法
【发布时间】:2013-10-23 13:49:16
【问题描述】:

如何在多个子类中实现一个超类中定义的泛型方法? 我需要由调用子类实例的类型决定正确的子类方法:

var someClassObj = new SubClass();
var = someClassObj.BuildList(v1, v2);

public abstract class SomeBase
{
    public List<T> BuildList<T>(int v1, int v2)
    {
        var results = new List<T>();

        for (int i = v1; i < v2; i++)
        {
            results.Add(AddItem<T>());
        }
        return results;
    }

    protected abstract T AddItem<T>();
}

public class SubClass : SomeBase
{


    protected override BusinessThing AddItem<T>()
    {
        var entity = new BusinessThing();
        entity.Name1 = "1";
        entity.Name2 = "2";
        entity.Name3 = "3";
        return entity;
    }
}

public class BusinessThing
{
    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Name3 { get; set; }
}

上述内容不成立:覆盖方法'T SomeBase.AddItem()'时无法更改返回类型

【问题讨论】:

  • 你尝试过 someClassObj.BuildList(v1, v2); 吗?

标签: c# generics inheritance


【解决方案1】:

你可以让你的基类通用而不是它的方法:

public abstract class SomeBase<T>
{
    public List<T> BuildList(int v1, int v2)
    {
        var results = new List<T>();

        for (int i = v1; i < v2; i++)
        {
            results.Add(AddItem());
        }
        return results;
    }

    protected abstract T AddItem();
}

public class SubClass : SomeBase<BusinessThing>
{
    protected override BusinessThing AddItem()
    {
        var entity = new BusinessThing();
        entity.Name1 = "1";
        entity.Name2 = "2";
        entity.Name3 = "3";
        return entity;
    }
}

【讨论】:

    【解决方案2】:

    如果你不想像 Daniel 建议的那样使用泛型类,你也可以告诉编译器 T 使用 where 子句来限制泛型类型:

    public abstract class SomeBase
    {
        public List<T> BuildList<T>(int v1, int v2) where T: BusinessThing
        {
            var results = new List<T>();
    
            for (int i = v1; i < v2; i++)
            {
                results.Add(AddItem<T>());
            }
            return results;
        }
    
        protected abstract T AddItem<T>() where T:BusinessThing;
    }
    
    public class SubClass : SomeBase
    {
        protected override T AddItem<T>()
        {
            var entity = new BusinessThing();
            entity.Name1 = "1";
            entity.Name2 = "2";
            entity.Name3 = "3";
            return (T)entity;
        }
    }
    

    然后按如下方式使用:

    var someClassObj = new SubClass();
    var list = someClassObj.BuildList<BusinessThing>(5, 7);
    

    这也允许您使用派生自 BusinessThing 的 ConcreteBusinessThing 类,该类也应使用:

    public class SubClass : SomeBase
    {
        protected override T AddItem<T>()
        {
            var entity = new ConcreteBusinessThing();
            entity.Name1 = "1";
            entity.Name2 = "2";
            entity.Name3 = "3";
            return (T)(object)entity; // ugly cast but is always ok
        }
    }
    

    并调用它:

    var someClassObj = new SubClass();
    var list = someClassObj.BuildList<ConcreteBusinessThing>(5, 7);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多