2012-03-19 14 views
5

Ben var aşağıdaki arayüz bildirimleri:İki benzer beton nesneyi C# içindeki jenerikleri uygulayan arabirim parametreleriyle bir yönteme nasıl geçiririm?

interface IOrder<T> where T: IOrderItem 
{ 
    IList<T> Items { get; set; } 
} 

interface IDistro<T> : IOrder<T> where T: IOrderItem 
{ 

} 

Öyle gibi iki somut sınıfları:

public static void UpdateDistro(IDistro<IOrderItem> distro) 
{ 

} 
:

// DistroItem implements IOrderItem 
public class Distro : IDistro<DistroItem> 
{ 
    public IList<DistroItem> Items { get; set; } 
} 

// PerishableOrderItem implements IOrderItem 
public class PerishableOrder : IDistro<PerishableOrderItem> 
{  
    public IList<PerishableOrderItem> Items { get; set; } 
} 

Son olarak, veritabanına kaydetmek için statik bir hizmet yöntemine sahip

Sorun şu ki, statik yöntemime beton türlerinden birini nasıl dağıtabilirim? Aşağıdaki derleme değildir:

Distro d = new Distro(); 
UpdateDistro(d); 

hatadır:

The best overloaded method match for UpdateDistro(IDistro<IOrderItem>)' has some invalid arguments

cevap contravariance mı? Orijinal arayüz bildirimi için <in T> eklemeyi denedim, ancak bu, çözemediğim daha fazla hata ekledi. Bu benim ilk derinlikli arayüzlere giriyor ve eminim jeneriklerin karmaşıklık kattığından eminim, bu yüzden burada temel bir anlayış eksikliği olabilir.

:

public static void UpdateDistro<T>(IDistro<T> distro) 
    where T : IOrderItem 
{ 
} 

DÜZENLEME: DistroItem ve PerishableItem sınıflar (her ikisi IOrderItem uygulayan), bir hata olmadan derleme aşağıdaki var boş uygulamaları ile

cevap

6

bu denediniz
Distro d = new Distro(); 
PerishableOrder p = new PerishableOrder(); 

UpdateDistro(d); 
UpdateDistro(p); 
+0

Evet, bunu denedim. Distro' nesnesini geçerken hala şikayet ediyordu. UpdateDistro (myDistro) 'aynı hatayı attı. – IronicMuffin

+0

Bunun görüldüğünü görüyorum. Yöntemi çağırmanın uygun yolunu gösterebilirseniz, bunu cevap olarak işaretleyeceğim. – IronicMuffin

+0

Teşekkür ederiz. Acı çektiğim için üzgünüm. Arabirim türlerine, vb. Yerleştirdiğim diğer testlerden kalanlar vardı. İstenildiği gibi çalışıyor. Çok takdir! – IronicMuffin

0

Arayüzünüzde bir kovaryant jenerik parametre tanımlayabilirsiniz, arayüzü biraz değiştirmelisiniz ,

public interface IOrder<out T> where T : IOrderItem 
{ 
    IEnumerator<T> Items { get; } 
} 

public interface IDistro<out T> : IOrder<T> where T : IOrderItem 
{ 

} 

coverient parametresi (out) halinde T tanımlamak için Varyant arabirimlerini sınıfların örtülü dönüşüm sağlar: T olmadığından emin olmak için olsa contravariantly kullanır.