Это должно работать:
public interface IBar
{
T DoBarStuff<T>() where T : class, new();
}
public class Bar : IBar
{
public T DoBarStuff<T>() where T : class, new()
{
// do bar stuff
return new T();
}
}
Но вы должны указать тип при использовании метода DoBarStuff
:
Использование:var fooStuff = _foo.DoBarStuff<FooWhatEver>().GetFooStuff(id)
Если вы не захотите, сделайте свой общий класс/интерфейс:
public interface IBar<T> where T : class, new()
{
T DoBarStuff<T>();
}
public class Bar<T> : IBar<T> where T : class, new()
{
public T DoBarStuff()
{
// do bar stuff
return new T();
}
}
Использование:
IBar bar = new Bar<FooWhatEver>();
var fooStuff = _foo.DoBarStuff().GetFooStuff(id);
Но все это не работает для интерфейса, только инстанциируемые классов (с конструктором по умолчанию).
Для интерфейсов вам нужно что-то сделать для преобразования между ними и их реализациями.
Простым способом является использование словаря (для целей тестирования, но вы можете использовать инфраструктуру инъекций зависимостей, как предлагалось @N_tro_P, даже если вы выбрали между одним из них, теперь не должна быть вашей главной целью).
Вы будете в конечном итоге с чем-то вроде этого (не забудьте наследуйте и общей части):
public class Bar // <T> or not depending on your choice
// You can add this constraint to avoid value types (as int):
// where T : class
{
Dictionary<Type, Type> _container = new Dictionary<Type, Type>();
{
{typeof(IFoo), typeof(Foo)}
};
public T DoBarStuff() // <T> or not depending on your choice
// You can add this constraint to avoid value types (as int):
// where T : class
{
// get fooStuff
return Activator.CreateInstance(_container[typeof(T)]);
// You will get an error if T is not in the container
// or if _container[typeof(T)] is not instantiable
// or doesn't have a default constructor.
}
}
Единственная проблема, вам придется заполнить словарь/контейнер со всеми интерфейсами/классы, которые вы хотите использовать, это может стать довольно неприятным для решения. Вместо этого вы можете предпочесть использовать одно из моих первых решений.
Подсказка: вы должны вернуть экземпляр Т, а не тип самого Т ... – ViRuSTriNiTy
'T' - это тип. 'return T;' похоже на запись 'return int;'. Вернуть * что * int? Если ваш метод создал объект с типом T, верните его. Если вы не собираетесь ничего возвращать, не используйте возвращаемое значение в определении, используйте 'void'. –
Посмотрите на это: http://stackoverflow.com/questions/731452/create-instance-of-generic-type#answer-731637 – Corporalis