C#: dönüş türü Geçersiz kılma
C dönüş türü geçersiz kılmak için bir yolu var# mı? Nasıl, neden ve ne tavsiye bir yolu nedir?
Benim durumumda soyut temel sınıf ve torunları ile bir arayüzü var. Bunu yapmak için (aslında değil, ama bir örnek olarak ok!) istiyorum :
public interface Animal
{
Poo Excrement { get; }
}
public class AnimalBase
{
public virtual Poo Excrement { get { return new Poo(); } }
}
public class Dog
{
// No override, just return normal poo like normal animal
}
public class Cat
{
public override RadioactivePoo Excrement { get { return new RadioActivePoo(); } }
}
Elbette RadioactivePoo
Poo
devralır.
Benim sebeple isteyen bu yüzden o kim kullanma Cat
nesneleri işime yarar Excrement
özelliği olmadan olması için döküm Poo
RadioactivePoo
süre örnek Cat
diye hala bir Animal
liste nerede kullanıcıların olmayabilir mutlaka farkında olun ya da bakımı ile ilgili kendi radyoaktif kaka. Umarım bunun mantıklı...
Derleyici buna izin vermez görebildiğim kadarıyla en azından. Sanırım bu yüzden mümkün değildir. Ama bu bir çözüm olarak ne önerirsiniz?
CEVAP
Ne genel bir temel sınıf hakkında?
public class Poo { }
public class RadioactivePoo : Poo { }
public class BaseAnimal<PooType>
where PooType : Poo, new() {
PooType Excrement {
get { return new PooType(); }
}
}
public class Dog : BaseAnimal<Poo> { }
public class Cat : BaseAnimal<RadioactivePoo> { }
EDİTYeni bir çözüm, uzatma yöntemleri ve bir işaretleyici arayüzü kullanarak...
public class Poo { }
public class RadioactivePoo : Poo { }
// just a marker interface, to get the poo type
public interface IPooProvider<PooType> { }
// Extension method to get the correct type of excrement
public static class IPooProviderExtension {
public static PooType StronglyTypedExcrement<PooType>(
this IPooProvider<PooType> iPooProvider)
where PooType : Poo {
BaseAnimal animal = iPooProvider as BaseAnimal;
if (null == animal) {
throw new InvalidArgumentException("iPooProvider must be a BaseAnimal.");
}
return (PooType)animal.Excrement;
}
}
public class BaseAnimal {
public virtual Poo Excrement {
get { return new Poo(); }
}
}
public class Dog : BaseAnimal, IPooProvider<Poo> { }
public class Cat : BaseAnimal, IPooProvider<RadioactivePoo> {
public override Poo Excrement {
get { return new RadioactivePoo(); }
}
}
class Program {
static void Main(string[] args) {
Dog dog = new Dog();
Poo dogPoo = dog.Excrement;
Cat cat = new Cat();
RadioactivePoo catPoo = cat.StronglyTypedExcrement();
}
}
Bu şekilde Köpek ve Kedi Hayvan (yorum söylediği gibi, benim ilk çözüm mirası korumak değil) devralır.< / ^ br . Gerekli acı verici bir işaret arabirimi ile açıkça sınıfları işaretlemek için, ama belki bu size bazı fikirler verebilir...
İKİNCİ DÜZENLEME@Svish: uzatma yöntemi herhangi bir şekilde iPooProvider
BaseAnimal
devraldığı gerçeğini zorlanarak değil explitly göstermek için kodu değiştirdim. Ne demek "daha da güçlü-daktilo"?
Neden önemli GetHashCode yöntem geçers...
döküm kullanılmayan dönüş geçersiz değ...
Geçersiz kılma !önemli stil...
Geçersiz kılma ASP.NET Öznitelik Yetki...
Java dinamik bağlama ve yöntem geçersi...