SORU
26 HAZİRAN 2009, Cuma


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
26 HAZİRAN 2009, Cuma


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"?

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Christian Atlas

    Christian At

    26 Mart 2009
  • EminemMusic

    EminemMusic

    9 ŞUBAT 2007
  • kylelandry

    kylelandry

    9 AĞUSTOS 2007