繁体   English   中英

C#:对子类类型的通用方法约束

[英]C#: generic method constraint on subclassed types

我有两种基类:

public class Parent { }
public abstract class Child : Parent 
{
    string ChildKey { get; set; }
}

来自父母,有很多孩子:

public class Kid1 : Parent { public string Name { get; set; } }
public class Kid2 : Parent { public long Number { get; set; } }
...

还有许多儿童是特殊的儿童群体,具有额外的属性:

public class Child1 : Child { public string Street { get; set; } }
public class Child2 : Child { public long Account { get; set; }}

现在,我有两个通用的存储库类,其中的“特殊的”通过使用附加的过滤器在附加属性上表现得更加具体:

public class Repository<T> : IRepository<T> where T : Parent 
{ 
    public IEnumerable<T> GetAll() { return something; }
}
public class ChildRepository<T> : Repository<T>, IChildrenRepository<T> where T : Child 
{ 
    public override IEnumerable<T> GetAll() { return base.GetAll().Where(x => x.ChildKey == "y"); }
}

与接口:

public interface IRepository<T> where T : Parent
{ IEnumerable<T> GetAll(); }
public interface IChildRepository<T> : IRepository<T> where T : Child { }

我还需要GetAll()结果的类型安全。

现在,我需要一个通用方法来创建所需的存储库:

IRepository<T> GetRepository() where T : WhatConstraint
{
    if (typeof(Child).IsAssignableFrom(T))
        return new ChildRepository<T>();    // return 1
    return new Repository<T>();             // return 2
}

正确的约束是什么? return 1需要Child-Constraint(对于Return 2是错误的),它表示类型T不能用作方法中的类型参数,因为没有从T到Child的隐式引用转换。

T:Child-constraint在ChildRepository中更为精确(因此很有用,因为我可以依赖某些属性)。 如果我使用相同的T:存储库的父约束,则必须一直检查T是否始终从Child派生...

有什么解决办法吗?

好的,这是一个详细的解决方案(可以写得更短也更不易读)。 由于存储库和ChildRepository具有冲突的约束(这对存储库有利,但对GetRepository-factory不利),因此无法使用new-keyword创建ChildRepository。 我必须通过CreateInstance创建此对象。

IRepository<T> GetRepository() where T : Parent
{
    if (typeof(Child).IsAssignableFrom(T))
    {
        Type childType = typeof(T);  // which is both, Parent and Child
        Type classType = typeof(ChildRepository<>);
        Type[] typeParams = { childType };
        Type repositoryType = classType.MakeGenericType(typeParams);
        return Activator.CreateInstance(resultType) as IRepository<T>;
    }
    return new Repository<T>();
}

该解决方案的缺点:更复杂的代码分析,不清楚的结果可为空性,不是真正直观的可读性(尤其是现有的约束)。 但这有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM