Подтвердить что ты не робот

Устранение методов расширения/неопределенность LINQ

Я пишу надстройку для 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>)

EDIT: Я попробовал следующее предложение, к сожалению, без везения. В то же время я "решил" проблему, удалив ссылки на System.Core. Таким образом, я мог бы использовать расширения, предоставляемые файлами ReSharper DLL.

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Затем в вашем коде напишите:

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

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

Ответ 3

На самом деле это не ответ, но может дать более простой способ воспроизвести проблему другим пользователям (из командной строки - вы можете сделать это с двумя проектами в 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, указав псевдоним extern:

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

Это не выполняется:

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

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

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

Ответ 4

Чтобы ReSharper был максимально совместим с множеством решений, с которыми он используется, он построен на .NET 2.0. LINQ и т.д. Вошли в С# 3.0, поэтому они недоступны в этой версии Framework. Итак, JetBrains добавили в свою версию.

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

У меня была аналогичная ситуация. После двухчасового боя я понял, что у меня есть дубликаты имен имен в моих библиотеках. Если вы используете файл 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
{

Ответ 10

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

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 вызвал ошибку неоднозначности; явно набрасывая результаты, а затем вызывая расширение на том, что сработало.