12

Tengo dos métodos de extensión:sobrecargar elección

public static IPropertyAssertions<T> ShouldHave<T>(this T subject) 
{ 
    return new PropertyAssertions<T>(subject); 
} 

public static IPropertyAssertions<T> ShouldHave<T>(this IEnumerable<T> subject) 
{ 
    return new CollectionPropertyAssertions<T>(subject); 
} 

Ahora escribir un código que lo utiliza:

List<Customer> collection2 = new List<Customer>(); 
collection2.ShouldHave(); //first overload is chosen 
IEnumerable<Customer> collection3 = new List<Customer>(); 
collection3.ShouldHave(); //second overload is chosen 

Segunda sobrecarga se elige sólo si puedo especificar explícitamente el tipo IEnumerable. ¿Hay alguna forma de hacer que la segunda sobrecarga sea elegida en ambos casos?

+0

No habrá diferencia entre '' collection1' y collection2'. Son exactamente el mismo código, solo escrito de manera diferente. – svick

+0

@svick, sí, pero quería mostrar todas las opciones de sintaxis – SiberianGuy

+3

Tenga en cuenta que el hecho de que sea un método de extensión es irrelevante; la resolución de sobrecarga lo maneja como un método estático normal. –

Respuesta

5

No lo creo. No creo que sea posible que en este caso IEnumerable<T> se llame siempre a la sobrecarga, ya que tiene menos coincidencia exacta con respecto al tipo T. Si no especifica un concreto IEnumerable<T>, la mejor coincidencia será siempre un primer método, en este caso.

7

La primera de sobrecarga es un partido mejor, porque T se infiere como List<Customer>, lo que da una coincidencia exacta. Para la segunda sobrecarga, inferiría T como Customer, por lo que el parámetro sería IEnumerable<Customer>, que es una coincidencia menos exacta que List<Customer>.

1

shouldhave() tiene un doble significado. En el primer caso, ShouldHave() tiene un retorno sobre el objeto proporcionado por el sujeto-parámetro. En el segundo caso, la devolución se trata de elementos en la enumeración, y no de la enumeración en sí misma.

En caso de que cree mi propia colección y quiera probar esta colección en sí (no los artículos), ciertamente quiero que ShouldHave (este sujeto T) sea llamado y no ShouldHave (este tema IEnumerable).

Tal vez debería reconsiderar su diseño. El segundo ShouldHave() hace dos cosas, por lo que debe dividirse en un método que extraiga los elementos de colección y una llamada al primer ShouldHave(), que ya tiene.

+0

eso es exactamente lo que estamos tratando hacer, pero tenemos algunos problemas con la resolución de sobrecarga del compilador de C#. –

+0

El compilador de C# es correcto en el sentido de que prefiere la coincidencia perfecta con una coincidencia que primero necesita una conversión de tipo. Creo que su diseño es imperfecto y quiere que el compilador de C# también lo resuelva. ¿Qué sucede si de verdad quiero aplicar ShouldHave (este tema T) a mi colección? ¿Por qué quieres bloquear este escenario? –

+0

Me gusta ser imperfecto :-) –