method how extension extended custom create c# .net visual-studio-2008 linq extension-methods

c# - how - Resolución de métodos de extensión/ambigüedad LINQ



system.linq c# (10)

Estoy escribiendo un complemento para ReSharper 4. Para esto, necesité hacer referencia a varios ensambles de ReSharper. Uno de los ensamblados (JetBrains.Platform.ReSharper.Util.dll) contiene un espacio de nombres System.Linq , con un subconjunto de métodos de extensión que ya proporciona System.Core.

Cuando edito el código, crea una ambigüedad entre esas extensiones, por lo que no puedo usar OrderBy , por ejemplo. ¿Cómo podría resolver esto? Me gustaría usar las extensiones LINQ centrales, y no las de ReSharper.

Me aparece el siguiente error al intentar compilar:

La llamada es ambigua entre los siguientes métodos o propiedades: '' System.Linq.Enumerable.OrderBy<string,int>(System.Collections.Generic.IEnumerable<string> , System.Func<string,int>)'' and ''System.Linq.Enumerable.OrderBy<string,int>(System.Collections.Generic.IEnumerable<string>, System.Func<string,int> ) ''

EDITAR: Probé la sugerencia a continuación, desafortunadamente sin suerte. Mientras tanto, "resolví" el problema eliminando las referencias a System.Core . De esta forma podría usar las extensiones proporcionadas por los archivos DLL de ReSharper.

Cargué un programa de ejemplo donde acabo de importar los archivos DLL de ReSharper que necesitaba. Cambié el alias de System.Core a SystemCore , agregué la directiva extern alias , pero todavía no funcionaba. Si me perdí algo, házmelo saber. PS Las referencias son a los archivos DLL de ReSharper v4.1 instalados en el directroy predeterminado en "C:/Program Files/JetBrains/ReSharper/v4.1/..." .


Encontré este mismo tipo de ambigüedad cuando uso PagedList en MVC (.Net 4.5, MVC 5). Descubrí que si tomé el objeto para el argumento que era ambiguo y lo expuse explícitamente primero, el problema se resolvió. A si la ambigüedad era entre un método que toma System.Linq.Enumerable y uno que toma System.Collections.Generic.IEnumerable como el parámetro en cuestión, y la fuente es del tipo System.Collections.Generic.IEnumerable, no lo hago usa el método de extensión en él. Lo echo. En este ejemplo, mi método de repositorio devuelve una lista:

searchRequest.CaseSearchResults = csr.SelectMatchingCases(searchRequest); var results = searchRequest.CaseSearchResults.AsEnumerable<CaseSearchResult>(); int pageNum = (int)(ViewBag.PageNum ?? 1); var pageResults =results.ToPagedList<CaseSearchResult>(pageNum, 5);

Llamar al método de extensión en searchRequest.CaseSearchResults causó el error de ambigüedad; echando explícitamente a los resultados y luego llamando a la extensión sobre eso funcionó.


Es realmente un error de compilación.

Tuve el mismo problema, y ​​lo resolví simplemente limpiando y reconstruyendo el proyecto. Después de eso, el problema desapareció.


Esta no es realmente una respuesta, pero puede proporcionar una manera más fácil para que otros reproduzcan el problema (desde la línea de comandos; puede hacerlo con dos proyectos en Visual Studio si lo desea).

1) Crear BadLinq.cs y compilarlo como BadLinq.dll:

using System.Collections.Generic; namespace System.Linq { public static class Enumerable { public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T,bool> predicate) { return null; } } }

2) Crear Test.cs:

extern alias SystemCore; using System; using SystemCore::System.Linq; static class Test { static void Main() { var names = new[] { "Larry", "Curly", "Moe" }; var result = names.Where(x => x.Length > 1); } }

3) Compile Test.cs especificando el alias externo:

csc Test.cs /r:BadLinq.dll /r:SystemCore=System.Core.dll

Esto falla con:

Test.cs (11,28): error CS1061: ''System.Array'' no contiene una definición para ''Where'' y no se puede encontrar ningún método de extensión ''Where'' que acepte un primer argumento de tipo ''System.Array'' (¿está usted? ¿falta una directiva using o una referencia de ensamblado?)

Si lo cambia para no intentar usar un método de extensión (es decir, Enumerable.Where), funciona bien con el alias externo.

Creo que esto puede ser un error del compilador. He enviado por correo electrónico una lista de correo privada que el equipo de C # lee: actualizaré esta respuesta o agregaré una nueva cuando reciba una respuesta.


Este es probablemente uno de esos raros casos en los que tiene sentido usar un alias externo .

En la página de propiedades para la referencia a System.Core (es decir, en Referencias, seleccione System.Core, haga clic con el botón derecho y seleccione "Propiedades"), cambie el valor de "Alias" a "global, SystemCore" (o simplemente "SystemCore" si está en blanco para comenzar).

Luego, en tu código, escribe:

extern alias SystemCore; using SystemCore::System.Linq;

Eso hará que todos los tipos relevantes, etc. en el espacio de nombres System.Core.dll System.Linq estén disponibles. El nombre "SystemCore" aquí es arbitrario; podría llamarlo "DotNet" u otra cosa si eso lo aclarara más.


Esto ya no es un problema, ya que puedo usar las extensiones de LINQ, tal como lo proporcionan los archivos DLL de ReSharper, incluso mientras estoy apuntando a .NET 3.0.

¡El Sr. Skeet tenía razón otra vez! ¡Puedo utilizar la sintaxis completa de LINQ, mientras apunté a .NET 3.0 en las propiedades del proyecto y no hago referencia a System.Core!


Para que ReSharper sea lo más compatible posible con la variedad de soluciones con las que se usa, está diseñado contra .NET 2.0. LINQ, etc. entró en C # 3.0, por lo que no están disponibles en esa versión del Framework. Entonces, JetBrains agregó en su propia versión.

La solución es construir su complemento contra .NET 2.0 también.


Tuve el mismo problema, incluso con un alias externo, y lo planteé como un error de compilación en Connect. La solución temporal por el momento es renunciar a la sintaxis del método de extensión.

El error está solucionado para Visual Studio 2010.


Tuve el problema de referencia ambiguo al usar System.ComponentModel. Visual Studio se quejaba de que existe un archivo DLL en v2 y v4. Pude resolverlo al eliminar la referencia al archivo DLL del sistema y leerlo.


Tuve una situación similar. Después de dos horas luchando, me di cuenta de que tenía nombres de nombres de espacios duplicados en mis bibliotecas. Si está utilizando el archivo Dynamic.cs publicado por Microsoft, lo único que debe hacer es cambiar el nombre del espacio de nombres actual a otra cosa, y se solucionará.

//Copyright (C) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; using System.Text; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Threading; namespace System.Linq.Dynamic <- for example to Linq.Dynamic {


Una solución sería mover todo su código a una clase parcial que utiliza el código ReSharper. Allí, importaría solo el espacio de nombres ReSharper y no System.Core.

En el resto de la clase parcial, importaría todos los otros espacios de nombres que necesite, incluido System.Core, pero no el espacio de nombres ReSharper.