4

This is perfectly valid:

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

That is, it defines an untyped interface that includes a method to get a IEnumerable of some type that implements IWidget.

How do I make this into a property?

Things that don't work:

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; }
Dave Mateer
  • 17,608
  • 15
  • 96
  • 149

2 Answers2

10

There is no such thing as a generic property.

A type parameter is still a kind of parameter. Just like you couldn't turn a method that takes an argument into a property, you can't turn a generic method into a property either.

The closest thing you could do is this:

public interface IWidgetGetter<T> where T : IWidget
{
    IEnumerable<T> Widgets { get; }
}
Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
1

@Lucas Trzesniewski answered but i would like to add that you can also use a different type parameter TOutput which becomes a generic type parameter instead of using type parameter on the interface definition T.

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

Then you can use TypeDescriptor.Converter which knows how to do conversions for primitive types or maybe leverage extension methods it really depends on your case.

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:
       }
    }
}
Matija Grcic
  • 12,963
  • 6
  • 62
  • 90