2017-02-06 17 views
10

varsayalım İki ilgisiz türleri ve aynı imzaya sahip iki uzatma yöntemleri ancak farklı tip filtreleri tanımlamış:C# jenerik yöntem çözünürlüğü belirsiz bir çağrı hatası ile başarısız

public class Foo {} 
public class Bar {} 

public static class FooExtensions 
{ 
    public static TFoo Frob<TFoo>(this TFoo foo) where TFoo : Foo { } 
    public static TFoo Brob<TFoo>(this TFoo foo) where TFoo : Foo { } 
} 

public static class BarExtensions 
{ 
    public static TBar Frob<TBar>(this TBar bar) where TBar : Bar { } 
} 
Sonra

ben new Foo().Frob(); yazarken bir hata alıyorum

Bu başarısız ve nasıl önlemek için neden

error CS0121: The call is ambiguous between the following methods or properties: 'FooExtensions.Frob<TFoo>(TFoo)' and 'BarExtensions.Frob<TBar>(TBar)'

birisi açıklayabilir misiniz?

DÜZENLEME: Bu, VS2015 Update 3 ve VS2017 RC'de gerçekleşir.

EDIT2:

new Foo() 
    .Frob() 
    .Brob() 
+0

Kabul edilen cevap doğrudur; Burada yaptığınız şeyin kötü bir uygulama olduğuna dikkat etmeliyim. Lütfen nesneyi genişleterek ya da genel tip T'yi genişleterek * her şeyi * uzatan uzatma yöntemleri kullanmayın. Hemen hemen her zaman daha iyi bir tasarım vardır. Bu durumda, neden sadece Foo ve Bar'ı genişletmiyorsunuz? Bu jenerik yapmak için ne kadar zorlayıcı bir avantaj var? –

+0

@EricLippert, senaryoyu oldukça basitleştirdim. Gerçekte, uzatma yöntemleri 'TFoo'yu döndürür. Buradaki fikir, bir sınıf hiyerarşisinde çalışan akıcı API yöntemlerine sahip olmaktır. Böylece yeni Foo() yazabilirim. Frob(). Grob(). Blob(); '. Sorun, iki bağımsız türüm olduğunda, ancak benzer sırayla benzer argümanları alan uzantı yöntemleriyle ortaya çıkar. –

cevap

11

bir genel tür parametre kısıtlaması yöntemin imzasının bir parçası değildir: Buradaki fikir, bir sınıf hiyerarşisi üzerinde çalışır akıcı API sahip olmaktır. Bu iki yöntem esasen bir çözüm bakış açısından aynıdır; derleyici aramayı çözümlemeye çalıştığında iki geçerli yöntem görür ve daha iyi olanı seçmenin bir yolu yoktur, bu nedenle çağrı belirsiz olarak işaretlenir.

Bu sorun hakkında daha fazlasını okuyabilirsiniz here.

+0

Bağlantı için teşekkürler; Kendimi daha iyi söyleyemedim. –

+3

@EricLippert Size çok teşekkürler, dil hakkında ne kadar öğrendiğimi ve genel olarak programlamayı, blogunuzu okurken abartmak zor. – InBetween

İlgili konular