2009-11-24 26 views
8

Yani, eminim bu daha önce bir yerde yanıtlanmış, ancak hiçbir yerde bulamadım. Bazı generics guru umuyor yardımcı olabilir.İşlem ile genel yöntem <T> parametresi

public interface IAnimal{} 
public class Orangutan:IAnimal{} 

public void ValidateUsing<T>(Action<T> action) where T : IAnimal 
{ 
    Orangutan orangutan = new Orangutan(); 
    action(orangutan); //Compile error 1 

    //This doesn't work either: 
    IAnimal animal = new Orangutan(); 
    action(animal); //Compile error 2 
} 
  1. değişken türü 'Orangutan' 'T'

Düzen türü parametre türü 'T'

  • değişken türü 'IAnimal' parametre atanabilir atanabilir değildir değildir: Tabanlı Yuriy ve diğer önerileri üzerine, elimden gelen bazı döküm gibi:

    public void ValidateUsing<T>(Action<T> action) where T : IAnimal 
    { 
        Orangutan orangutan = new Orangutan(); 
        action((T)(IAnimal)orangutan); 
    
        //This doesn't work either: 
        IAnimal animal = new Orangutan(); 
        action((T)animal); 
    } 
    

    yapmak istediğim şey böyle ValidateUsing yöntemini çağırın oldu:

    ValidateUsing(Foo); 
    

    Maalesef foo aşağıdaki gibiyse:

    açıkça türünü belirtmek zorunda
    private void Foo(Orangutan obj) 
    { 
        //Do something 
    } 
    

    Ben ValidateUsing çağrı

  • cevap

    6

    herhangi IAnimal kabul gerekiyordu, neden bir Orangutan başlatmasını gibidir:

    Orangutan orangutan = new Orangutan(); 
    Action<IAnimal> castedAction = action as Action<IAnimal>; 
    castedAction(orangutan); 
    
    +0

    Teşekkürler, sadece Orangutan'ı örnek olarak kullandım. Muhtemelen kötü olan. Eylemi herhangi bir IAnimal ile arayabilmek istiyorum. "Gerçek" kodda, IAnimal sınıfta özel bir alan olarak saklanır. Yani, hiçbir şeyi gerçekten oluşturmuyorum. –

    2

    Bunu deneyin.

    Orangutan orangutan = new Orangutan(); 
    action((T)(IAnimal)orangutan); 
    
    
    IAnimal animal = new Orangutan(); 
    action((T)animal); 
    
    +0

    Teşekkürler Stan! Yeterli bir itibara sahip olsaydım cevabını verirdim. –

    2

    şu değişiklikleri yapın?

    public void ValidateUsing<T>(Action<T> action) where T : IAnimal, new() 
    { 
        T animal = new T(); 
        action(animal); //Compile error 2 
    

    Eğer genel parametreyi yeniden, herhangi bir tür sorunları olmayacak ... kodunuzu neden çalışmıyor bakımından Şimdi

    , diyorsunuz ki hepsi bu T tipi, IAnimal'dan türetilecektir. Ancak, GiraffeOrangutan olarak kolayca yapılabilir, bu nedenle T türünde bir parametreye bir Orangutan veya IAnimal atayamazsınız.

    +0

    Merhaba Yuriy, bu çok iyi çalışıyor. Beni yolun bir parçası haline getiriyor (düzenle). Teşekkürler! –

    0
    public interface IAnimal { } 
    public class Orangutan : IAnimal { } 
    
    public void ValidateUsing<T>(Action<T> action) where T : IAnimal 
    { 
        Orangutan orangutan = new Orangutan(); 
        action((T)(orangutan as IAnimal)); // needs to be cast as IAnimal 
    
        //This doesn't work either: 
        IAnimal animal = new Orangutan(); 
        action((T)animal); // needs to be cast as T 
    } 
    

    Ayrıca bir arabirimin fark yaratması gibi görünüyor. Eğer soyut bir sınıf Hayvan yerine bir arabirim olsaydı, bu yapabilirdi:

    public abstract class Animal { } 
    public class Orangutan : Animal { } 
    
    public void ValidateUsing<T>(Action<T> action) where T : Animal 
    { 
        Orangutan orangutan = new Orangutan(); 
        action(orangutan as T); 
    
        //This doesn't work either: 
        Animal animal = new Orangutan(); 
        action(animal as T); 
    } 
    
    +0

    Merhaba çöl, detaylı cevap için teşekkürler. Arayüzleri soyut sınıflardan çok daha sık kullanma eğilimindeyim (iyilik kompozisyonu ve mirasa karşı iyilik), fakat bunun soyut bir sınıfla çalıştığını bilmek ilginçtir. –

    4

    şey, T arada IAnimal uygulayan bazı türünü temsil ettiğini.

    Eğer eylem türüne ait olabileceğini sırası geldiğinde tip T bir parametre almalıdır beyan çünkü Hatayla action(new Organatum()) derlemeye çalıştığınızda Yani, en, Fish diyelim - Eğer Organatum döküm olamaz Fish için, yapabilir misin?

    IAnimal arabirimini uygulayan bir türün parametresini alan herhangi bir eylemi tetiklemek istiyorsanız, yalnızca jenerikleri unutun ve Action<IAnimal>'u kullanın.

    HTH.

    İlgili konular