Разрешение методов расширения / неоднозначность LINQ - PullRequest
27 голосов
/ 17 января 2009

Я пишу надстройку для ReSharper 4. Для этого мне нужно было сослаться на несколько сборок ReSharper. Одна из сборок (JetBrains.Platform.ReSharper.Util.dll) содержит пространство имен System.Linq с подмножеством методов расширения, уже предоставленных System.Core.

Когда я редактирую код, он создает неоднозначность между этими расширениями, поэтому я не могу использовать, например, OrderBy. Как я мог решить это? Я хотел бы использовать основные LINQ расширения, а не расширения ReSharper.

Я получаю следующую ошибку при попытке компиляции:

Звонок между следующие методы или свойства: «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>) '

РЕДАКТИРОВАТЬ: Я попробовал предложение ниже, к сожалению, без удачи. Тем временем я «решил» проблему, удалив ссылки на System.Core. Таким образом, я мог бы использовать расширения, предоставляемые файлами ReSharper DLL.

Я загрузил пример программы , куда я только что импортировал нужные мне файлы DLL ReSharper. Я изменил псевдоним System.Core на SystemCore, добавил директиву extern alias, но она все равно не работала. Если я что-то пропустил, пожалуйста, дайте мне знать. Постскриптум Ссылки на DLL-файлы ReSharper v4.1, установленные в директории по умолчанию в "C:\Program Files\JetBrains\ReSharper\v4.1\...".

Ответы [ 10 ]

41 голосов
/ 17 января 2009

Это, вероятно, один из тех редких случаев, когда имеет смысл использовать внешний псевдоним .

На странице свойств для ссылки на System.Core (то есть в разделе «Ссылки» выберите System.Core, щелкните правой кнопкой мыши и выберите «Свойства»), измените значение «Псевдонимы» на «global, SystemCore» (или просто « SystemCore ", если пуст для начала).

Тогда в своем коде напишите:

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

Это сделает доступными все соответствующие типы и т. Д. В пространстве имен System.Core.dll System.Linq. Название «SystemCore» здесь произвольно - вы можете назвать его «DotNet» или что-то еще, если это сделает его более понятным для вас.

6 голосов
/ 17 января 2009

На самом деле это не ответ, но он может предоставить другим более простой способ воспроизвести проблему (из командной строки - вы можете сделать это с двумя проектами в Visual Studio, если хотите).

1) Создайте BadLinq.cs и создайте его как 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) Создать 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) Скомпилируйте Test.cs, указав внешний псевдоним:

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

Это не с:

Test.cs (11,28): ошибка CS1061: 'System.Array' не содержит определение для «где» и нет метод расширения «Где», принимающий первый аргумент типа 'System.Array' может быть найден (вам не хватает директивы using или ссылки на сборку?)

Если вы измените его, чтобы не пытаться использовать метод расширения (т.е. Enumerable.Where), он отлично работает с внешним псевдонимом.

Я думаю, что может быть ошибкой компилятора. Я отправил по электронной почте частный список рассылки, который читает команда C # - я обновлю этот ответ или добавлю новый, когда получу ответ.

2 голосов
/ 14 апреля 2011

Для того чтобы ReSharper был максимально совместим с различными решениями, с которыми он работает, он построен на .NET 2.0. LINQ и т. Д. Появились в C # 3.0, поэтому они недоступны в этой версии Framework. Итак, JetBrains добавлен в собственную версию.

Решение состоит в том, чтобы создать дополнение к .NET 2.0.

2 голосов
/ 18 января 2009

Это больше не проблема, поскольку я могу использовать расширения LINQ, предоставляемые файлами ReSharper DLL, даже при нацеливании на .NET 3.0.

г. Скит снова был прав! Я могу использовать полный синтаксис LINQ, ориентируясь на .NET 3.0 в свойствах проекта и не ссылаясь на System.Core!

1 голос
/ 29 августа 2013

У меня возникла неоднозначная проблема с использованием System.ComponentModel. Visual Studio жаловалась, что файл DLL существует как в v2, так и в v4. Мне удалось решить эту проблему, удалив ссылку на файл System DLL и прочитав ее.

0 голосов
/ 13 августа 2015

Я обнаружил такую ​​же двусмысленность при использовании PagedList в MVC (.Net 4.5, MVC 5). Я обнаружил, что если я возьму объект за аргумент, который был неоднозначным, и сначала приведу его явно, проблема будет решена. Если неоднозначность была между методом, который принимает System.Linq.Enumerable, и методом, который принимает System.Collections.Generic.IEnumerable в качестве рассматриваемого параметра, а источник имеет тип System.Collections.Generic.IEnumerable, я используйте метод расширения на нем. Я приведу его. В этом примере мой метод репозитория возвращает List:

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

Вызов метода расширения для searchRequest.CaseSearchResults вызвал ошибку неоднозначности; явное приведение к приводит к и последующему вызову расширения, которое сработало.

0 голосов
/ 17 сентября 2014

У меня была похожая ситуация. После двух часов борьбы я понял, что в моих библиотеках есть повторяющиеся имена пространств имен. Если вы используете файл Dynamic.cs, опубликованный Microsoft, единственное, что вам нужно сделать, это переименовать текущее пространство имен в другое, и оно будет исправлено.

//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
{
0 голосов
/ 05 ноября 2010

Это действительно ошибка компилятора.

У меня была та же проблема, и я решил ее, просто очистив и перестроив проект. После этого проблема исчезла.

0 голосов
/ 29 января 2010

У меня была такая же проблема, даже с внешним псевдонимом, и я поднял ее как ошибку компилятора в Connect. Обходной путь в настоящее время должен отказаться от синтаксиса метода расширения.

Исправлена ​​ошибка в Visual Studio 2010.

0 голосов
/ 18 января 2009

Одним из решений было бы переместить весь ваш код в частичный класс, который использует код ReSharper. Там вы бы импортировали только пространство имен ReSharper, а не System.Core.

В остальной части неполного класса вы импортируете все другие необходимые вам пространства имен, включая System.Core, но не пространство имен ReSharper.

...