【问题标题】:How to use a generic type parameter as type parameter for a property declared as an interface with type constraints?如何将泛型类型参数用作声明为具有类型约束的接口的属性的类型参数?
【发布时间】:2015-05-11 07:32:41
【问题描述】:

如何声明和使用泛型接口(请参阅命名空间 Sample2)以与命名空间 Sample1 中的类相同的方式工作?

我知道有一种解决方法(请参阅命名空间 Sample2Modified),但这不是我想要实现的。


适用于类

使用类时,效果很好:

namespace Sample1
{
    public class ClassContainer<T1, T2>
        where T1 : T2
    { }

    public class ClassParent
    { }

    public class ClassChild : ClassParent
    { }

    public class ClassSampleDoesWork<TItem>
        where TItem : ClassParent
    {
        ClassContainer<IEnumerable<TItem>, IEnumerable<ClassParent>> SomeProperty { get; set; }
    }
}

不适用于接口

但是,对于接口,编译器在 ClassSampleDoesNotWork 中声明属性时会发出此警告:

Error 16 The type 'System.Collections.Generic.IEnumerable<TItem>'
cannot be used as type parameter 'T1' in the generic type or method
'Sample2.IInterfaceContainer<T1,T2>'. There is no implicit reference
conversion from 'System.Collections.Generic.IEnumerable<TItem>' to
'System.Collections.Generic.IEnumerable<Sample2.IInterfaceParent>'.

代码:

namespace Sample2
{
    public interface IInterfaceContainer<T1, T2>
        where T1 : T2
    { }

    public interface IInterfaceParent
    { }

    public interface IInterfaceChild : IInterfaceParent
    { }

    public class ClassSampleDoesNotWork<TItem>
        where TItem : IInterfaceParent
    {
        IInterfaceContainer<IEnumerable<TItem>, IEnumerable<IInterfaceParent>> SomeProperty { get; set; }
    }
}

修改后的版本有效,但这不是我真正想要的

如果我将类修改为使用 TEnumerableOfItem 而不是 TItem,它会起作用:

namespace Sample2Modified
{
    public interface IInterfaceContainer<T1, T2>
        where T1 : T2
    { }

    public interface IInterfaceParent
    { }

    public interface IInterfaceChild : IInterfaceParent
    { }

    public class ClassSampleModifiedDoesWork<TEnumerableOfItem>
        where TEnumerableOfItem : IEnumerable<IInterfaceParent>
    {
        IInterfaceContainer<TEnumerableOfItem, IEnumerable<IInterfaceParent>> SomeProperty { get; set; }
    }
}

【问题讨论】:

  • 带有类的版本不适合我。
  • @AhmedKRAIEM 它对我有用。

标签: c# generics


【解决方案1】:

尝试将class 约束添加到TItem

namespace Sample2
{
    public interface IInterfaceContainer<T1, T2>            
        where T1 : T2
    { }

    public interface IInterfaceParent
    { }

    public interface IInterfaceChild : IInterfaceParent
    { }

    public class ClassSampleDoesNotWork<TItem>
        where TItem : class, IInterfaceParent
    {
        IInterfaceContainer<IEnumerable<TItem>, IEnumerable<IInterfaceParent>> SomeProperty { get; set; }
    }
}

这是可行的,因为方差仅适用于引用类型(或存在身份转换)。不知道TItem 是引用类型,除非您添加: class。 阅读this 文章了解更多信息。 以下是演示此行为的示例代码:

IEnumerable<Object> items = new List<int>(); // Compiler error.

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多