interface IRepo<out T> where T: IModel {
}
Güzel, çalışıyor ..
interface IModel {}
class MyModel : IModel {}
interface IRepo<T> where T: IModel {
}
class Repo : IRepo<MyModel> {
}
// Cannot implicitly convert.. An explicit convertion exists. Missing cast?
IRepo<IModel> repo = new Repo();
yüzden kovaryansını ihtiyacım .. Bazı örneklerle sorunlarımı anlatacağım düşünüyorum. Sonra kullanmak istiyorum:
interface IRepo<out T> where T: IModel {
T ReturnSomething();
}
class Repo : IRepo<MyModel> {
public MyModel ReturnSomething() { return default(MyModel); }
}
Tüm iyi, ancak repo da nesneler eklemek gerekiyor.
// Invalid variance: The type parameter 'T' must be contravariantly valid on 'IRepo<T>.InsertSomething(T)'. 'T' is covariant.
interface IRepo<out T> where T: IModel {
T ReturnSomething();
void InsertSomething(T thing);
}
class Repo : IRepo<MyModel> {
public MyModel ReturnSomething() { return default(MyModel); }
public void InsertSomething(MyModel thing) { }
}
Yani iki parametre eklemeye çalıştığınızda: bir out parametresi ile, bunu yapamaz
interface IRepo<out TReturn, TInsert>
where TReturn : IModel
where TInsert : IModel
{
TReturn ReturnSomething();
void InsertSomething(TInsert thing);
}
Ve ilk örnekte olduğu gibi aynı hatayı alıyorum. in TInsert
Aynı hata iletisini aldığımda, hem yerleştirmeyi hem de getirmeyi nasıl destekleyebilirim?
DÜZENLEME: Ben olası bir çözüm bulduk, ama bu kadar optimum
interface IRepo<out TResult> where TResult : IModel {
TResult ReturnSomething();
// I need to duplicate my constraint here..
void InsertSomething<TInsert>(TInsert thing) where TInsert : IModel;
}
class Repo : IRepo<MyModel> {
public MyModel ReturnSomething() { return default(MyModel); }
// ... And here
public void InsertSomething<T>(T thing) where T: IModel { }
}
EDIT2 den: Eric cevaben: Bu ben ne daha tam örnektir elde etmeye çalışıyorum. Kovaryansı gerçekten çok istiyorum, böylece IRepo örneklerini gruplayabiliyorum ve yine de modeli örnek olarak kullanarak ekleme/güncelleştirme yöntemlerine sahip olmasını istiyorum. Öğeleri eklemek için derleme zamanı türü güvenliği alamıyorum, ancak bu kullanım durumu için yalnızca öğeleri okumam gerekiyor.
interface IModel { }
class SomeModel : IModel { }
class OtherModel : IModel { }
interface IRepo<T>
{
T ReturnSomething();
void AddSomething(T thing);
}
interface ISubRepo<T> : IRepo<T> where T : IModel { }
class SomeSubRepo : ISubRepo<SomeModel> {
public SomeModel ReturnSomething() { return default(SomeModel); }
public void AddSomething(SomeModel thing) { }
}
class OtherSubRepo : ISubRepo<OtherModel> {
public OtherModel ReturnSomething() { return default(OtherModel); }
public void AddSomething(OtherModel thing) { }
}
class Program {
static void Main(string[] args)
{
ISubRepo<IModel>[] everyone = new ISubRepo<IModel>[] {
new SomeSubRepo(),
new OtherSubRepo()
};
WorkOnAll(everyone);
}
static void WorkOnAll(IEnumerable<ISubRepo<IModel>> everyone)
{
foreach(ISubRepo<IModel> repo in everyone) {
IModel model = repo.ReturnSomething();
// Etc.
}
}
}
Sorunun ne olduğunu tam olarak anlamakta zorlanıyorum. Herhangi bir kod parçasının neden çalışmadığını soruyor musunuz? Eğer öyleyse, neden bu biraz farklı bir davranış göstermesi gerektiğine inandığınız kısa bir açıklama ile birlikte kod verebilir misiniz? –
@Eric: Daha eksiksiz bir örnek ekledim. Umarım bu biraz açıklar. – simendsjo