Функция, которую вы хотите использовать, называется " тип возвращаемой ковариации ", и это недопустимо (к сожалению) в языке программирования C #.
В некоторых других языках, таких как C ++, Java или Eiffel (и некоторых других), вы можете использовать более конкретный тип при переопределении виртуального метода или реализации интерфейса.
Если вы имеете дело с интерфейсом, вы можете использовать известную идиому (как упомянул Флориан): вы можете явно реализовать свой интерфейс и добавить другой метод с другой сигнатурой.
public interface IMyDbSet
{
IEnumerable<User> Users { get; }
}
public class ConcreteDbSet : IMyDbSet
{
IEnumerable<User> IMyDbSet.Users {get {return Users;}}
public DbSet<User> Users { get; set; }
}
Другой вариант - универсальный пользователь IMyDbSet<T>
аналогично bool Equals(object rhs)
из System.Object
и универсальный типобезопасный интерфейс [IEquatable<T>][2]
:
public interface IMyDbSet<T> where T : IEnumerable<User>
{
// Because T is IEnumerable<User> or one of it descendant
// this property is similar to IEnumerable<User> Users {get;}
T Users {get;}
}
// Now we're implementing not IMyDbSet interface itself
// but we're IMyDbSet<IList<User>> instead.
// Note you could use your own descendant for IEnumerable<User> here
public class ConcreteDbSet : IMyDbSet<IList<User>>
{
public IList<User> Users {get; set;}
}
//...
// and now you could use ConcreteDbSet following way:
var set = new ConcreteDbSet();
IList<User> users = set.Users;