【问题标题】:C#. Is is possible to have a static generic class with a base type constraint that has a method with a further base type constraintC#。是否可能有一个具有基类型约束的静态泛型类,该类具有具有进一步基类型约束的方法
【发布时间】:2010-08-13 15:15:24
【问题描述】:

我希望能够创建具有基本类型约束的静态泛型类型,例如

public static class Manager<T> where T : HasId
{
    public static T GetSingleById(ref List<T> items, Guid id)
    {
        // the Id is a property provided by HasId
        return (from i in items where i.Id == id select i).SingleOrDefault();
    }
}

然后添加另一个方法

...
    public static IEnumerable<T> GetManyByParentId(ref List<T> items, Guid parentId) where T : HasIdAndParentId
    {
        // the parentId is a property of HasIdAndParentId which subclasses HasId
        return from i in items where i.ParentId == parentId select i;
    }
...

由于 HasIdAndParentId 是 HasId 的子类,因此满足约束 T : HasId 但编译器不会接受该方法的 where 基类型约束。

有什么想法吗?

【问题讨论】:

  • 顺便说一句——在您的使用中,ref 关键字是不必要的。引用类型(即对象)总是通过引用传递; ref 仅表示引用本身可以通过方法修改(例如通过设置新的List&lt;T&gt;)。
  • 是的,我知道这个 Ben,但同时我想向我的其他开发人员清楚正在发生的事情,即传入的列表将被更改。

标签: c# generics types constraints base


【解决方案1】:

在这种情况下,您没有在方法上重新定义类型参数,因此您不能应用任何新的约束。你应该可以这样做:

public static IEnumerable<T2> GetManyByParentId<T2>(
    ref List<T2> items, Guid parentId) 
    where T2 : T, HasIdAndParentId { .. } 

【讨论】:

    【解决方案2】:

    GetManyByParentId 方法本身设为泛型,并将其泛型参数绑定到T

    public static IEnumerable<R> GetManyByParentId<R>(
                                        ref List<R> items, Guid parentId) 
           where R : T, HasIdAndParentId 
    

    【讨论】:

    • @Ben M:你是对的,我完全误解了这个问题......我已经更新了我的答案。看来我需要休息一下,喝杯咖啡:)
    【解决方案3】:

    除非 HasIdAndParentId 是接口类型,否则 Ben M 的代码示例将无法编译,从名称来看,它不是。

    将第二种方法本身设为通用并使其依赖于它自己的类型参数(与 T 不同)将为您提供所需的约束。

    public static IEnumerable<T1> GetManyByParentId<T1>(ref List<T1> items, Guid parentId) where T1 : HasIdAndParentId
    {
        // the parentId is a property of HasIdAndParentId which subclasses HasId
        return from i in items where i.ParentId == parentId select i;
    }
    

    【讨论】:

    • HasIdAndParentId 对我来说听起来像是一个(非常规命名的)接口;记住 has-a 与 is-a
    • HasId 不是一个接口,也不需要是一个;其中 T: HasId 是基本类型约束
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 2018-03-05
    相关资源
    最近更新 更多