如何在界面上创建通用约束属性?

时间:2014-12-17 18:01:44

标签: c# generics

这完全有效:

public interface IWidgetGetter
{
    IEnumerable<T> GetWidgets<T>() where T : IWidget;
}

也就是说,它定义了一个非类型化接口,其中包含一个方法来获取实现IEnumerable的某种类型的IWidget

如何将其变为属性?

不起作用的事情:

IEnumerable<T> Widgets<T> { get; set; } where T : IWidget
IEnumerable<T> Widgets { get; set; } where T : IWidget
IEnumerable<T> Widgets where T : IWidget { get; set; }
IEnumerable<T> Widgets<T> where T : IWidget { get; set; }

2 个答案:

答案 0 :(得分:10)

没有通用属性。

类型参数仍然是参数。就像你无法转换一个将参数带入属性的方法一样,你也无法将泛型方法转换为属性。

你能做的最接近的事是:

public interface IWidgetGetter<T> where T : IWidget
{
    IEnumerable<T> Widgets { get; }
}

答案 1 :(得分:1)

@Lucas Trzesniewski回答但我想补充一点,你也可以使用不同的类型参数TOutput,它变成泛型类型参数,而不是在接口定义T上使用类型参数。

 public interface MyInterface<T> : IEnumerable<T>
        {    
            IEnumerable<TOutput> AsEnumerable<TOutput>();     
        }

然后你可以使用知道如何为原始类型进行转换的TypeDescriptor.Converter,或者可以利用扩展方法,这实际上取决于你的情况。

public class MyClass<T> : MyInterface<T>
{
    public IEnumerable<TOutput> AsEnumerable<TOutput>()
    {
       var converter = TypeDescriptor. GetConverter(typeof(T));
       //do what you want
       foreach(var item in someList)
       {
           var result = converter.ConvertTo(item, typeof(TOutput));
           yield return (TOutput)result:
       }
    }
}