2016-03-29 11 views
2

Odak noktası derleme zamanında güçlü tür denetiminde olan bir akıcı bağımsız değişken onaylama kitaplığı uyguluyorum. Intellisense sadece iddia edilen tip için mevcut yöntemleri ve uzantıları göstermelidir.T Saydam Olduğu genel bir arabirimde yayımlama yöntemleri <K>

IEnumerable için bir uzantı oluştururken, uygun türde bağımsız değişkenleri çözerken sorun yaşıyorum. Bir içeriyorsa

public static IAssertion<T> ThrowIf<T>(this T t) 
{ 
    return new IfAssertion<T>(t); 
} 

Şimdi IEnumerable karşı kontrol etmek istiyorum:

kütüphanede Fikir size tip IAssertion bir onaylama işlemi örneğini döndürür herhangi tipine ThrowIf (veya ThrowIfNot) aramak olmasıdır belirli bir öğe. Gerçek türünün bir örneği alarak aşırı kullanıldığında

public static T1 Contains<T1, T2>(this IAssertion<T1> assertion, T2 item) 
    where T1 : IEnumerable<T2> 
{ 
    // assertion logic 
    return assertion.Value; 
} 

public static T1 Contains<T1, T2>(this IAssertion<T1> assertion, Func<T2, bool> func) 
    where T1 : IEnumerable<T2> 
{ 
    // assertion logic 
    return assertion.Value; 
} 

Her şey iyi giderse: Bir parametre olarak T türünde bir nesne alır ve diğer değerlendirme yapmak için bir işlev alır iki aşırı yükler olacaktır. Ama işlev derleyici ile ikinci bir döküm yapıldığında düzgün sürece tip argümanları tahmin edemediği: Ben fonksiyon parametresi için döküm yapmadan mutlu derleyici yapabilir herhangi bir yolu

var list = new List<string>(); 
list.ThrowIf().Contains("foo"); // compiles 
list.ThrowIf().Contains((string s) => false); // compiles 
list.ThrowIf().Contains(s => false); // does not compile 

var mı?

fazla uygulama ayrıntıları buradan bulunabilir: https://bitbucket.org/mikalkai/argument-assertions/overview

+0

'İçeriyor (s => false) –

+0

Hayır. Bunu çağırmanız gerekir , string> (s => false). – mikalkai

cevap

3

Destek IAssertioncovariant yapılabilir, bu cevap geçerlidir.

IAssertion eşdeğişkin olduğunu varsayarsak, mutlaka iki genel tür parametre Contains yöntemleri için T1 ve T2 gerekmez. Bunun yerine, doğrudan arayüzünde IEnumerable belirtmek ve bunun gibi tek genel tür parametresi kullanın:

public static IEnumerable<T> Contains<T>(this IAssertion<IEnumerable<T>> assertion, T item) 
{ 
    // assertion logic 
    return assertion.Value; 
} 

public static IEnumerable<T> Contains<T>(this IAssertion<IEnumerable<T>> assertion, Func<T, bool> func) 
{ 
    // assertion logic 
    return assertion.Value; 
} 

Sonra böyle yöntemini içerir kullanabilirsiniz: Ben yalnızca yapabilir düşünüyorum

var list = new List<string>(); 
list.ThrowIf().Contains("foo"); // compiles 
list.ThrowIf().Contains((string s) => false); // compiles 
list.ThrowIf().Contains(s => false); // compiles now too 
+0

IAssertion kovaryant olabilir ve kovaryanttır. Aslında uzantıyı doğrudan IEnumerable 'a bağlamayı denedim ama bir sebepten dolayı intellisense yöntemi bulamadığını söylüyordu. Ben sadece farklı bir makine ve tzadam üzerinde denedim, her şey iyi çalıştı! Intellisense şeyleri ilk kez vidalamaz. – mikalkai

İlgili konular