web-dev-qa-db-ja.com

拡張メソッド/ LINQのあいまいさの解決

ReSharper 4のアドインを作成しています。このため、ReSharperのアセンブリのいくつかを参照する必要がありました。アセンブリの1つ(JetBrains.Platform.ReSharper.Util.dll)には_System.Linq_名前空間が含まれており、System.Coreによってすでに提供されている拡張メソッドのサブセットが含まれています。

コードを編集すると、これらの拡張機能のあいまいさが生じるため、たとえばOrderByを使用できません。どうすればこれを解決できますか? ReSharperのものではなく、コア [〜#〜] linq [〜#〜] 拡張を使用したいと思います。

コンパイルしようとすると、次のエラーが発生します。

呼び出しは次のメソッドまたはプロパティの間であいまいです: '_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ファイルによって提供される拡張機能を使用できます。

I サンプルプログラムをアップロード ReSharperをインポートしたところDLL必要なファイル。_System.Core_のエイリアスをSystemCoreに変更しました。 _extern alias_ディレクティブを追加しましたが、それでも機能しませんでした。何か不足している場合は、お知らせください。PS参照は、ReSharper v4.1 DLL _"C:\Program Files\JetBrains\ReSharper\v4.1\..."_のデフォルトのディレクトリ。

28
Igal Tabachnik

.NET 3.0をターゲットにしている場合でも、ReSharper DLLファイルによって提供されるLINQ拡張機能を使用できるため、これは問題ではなくなりました。

スキート氏はまた正しかった! System.Coreを参照せずに、プロジェクトのプロパティで.NET 3.0をターゲットにしながら、完全なLINQ構文を使用できます。

2
Igal Tabachnik

これは、おそらく extern alias を使用することが理にかなっているまれなケースの1つです。

System.Coreへの参照のプロパティページ(つまり、[参照]で[System.Core]を選択し、右クリックして[プロパティ]を選択)で、[エイリアス]の値を "global、SystemCore"(または、最初は空白です)。

次に、コードに次のように記述します。

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

これにより、System.Core.dllのSystem.Linq名前空間のすべての関連タイプなどが利用可能になります。ここでの「SystemCore」という名前は任意です。「DotNet」などの名前を付けると、わかりやすくなります。

42
Jon Skeet

これは実際の答えではありませんが、他の人が問題を再現するためのより簡単な方法を提供する可能性があります(コマンドラインから-必要に応じて、Visual Studioの2つのプロジェクトで実行できます)。

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'には 'Where'の定義が含まれておらず、タイプ 'System.Array'の最初の引数を受け入れる拡張メソッド 'Where'が見つかりません( usingディレクティブまたはアセンブリ参照がありませんか?)

拡張メソッド(Enumerable.Whereなど)を使用しないように変更すると、externエイリアスで正常に機能します。

これはmayがコンパイラのバグだと思います。 C#チームが読むプライベートメーリングリストをメールで送信しました。返信があったら、この回答を更新するか、新しい回答を追加します。

6
Jon Skeet

ReSharperは、使用するさまざまなソリューションと可能な限り互換性を保つために、.NET 2.0をベースに構築されています。 LINQなどはC#3.0に含まれていたため、そのバージョンのフレームワークでは使用できません。したがって、JetBrainsは独自のバージョンで追加されました。

解決策は、.NET 2.0に対してもアドインをビルドすることです。

2
Nick Chadwick

System.ComponentModelを使用した参照のあいまいな問題がありました。 Visual Studioは、DLLファイルがv2とv4の両方に存在することを報告していました。システムへの参照を削除することで解決できましたDLLファイルと読み取りそれ。

1
Ujain

MVC(.Net 4.5、MVC 5)でPagedListを使用すると、これと同じ種類のあいまいさが見つかりました。あいまいな引数のオブジェクトを取り、それを最初に明示的にキャストすると、問題が解決されることがわかりました。 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で拡張メソッドを呼び出すと、あいまいなエラーが発生しました。 resultsに明示的にキャストしてから、その上で拡張機能を呼び出して機能しました。

0
Joey Morgan

私も同じような状況でした。 2時間苦闘した後、ライブラリに名前空間名が重複していたことに気付きました。 Microsoftが公開しているファイルDynamic.csを使用している場合、現在のネームスペースの名前を別の名前に変更するだけで、修正されます。

//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
Ryan

Externエイリアスを使用しても同じ問題が発生しましたが、Connectで コンパイラバグとして発生させました です。当面の回避策は、拡張メソッドの構文を忘れることです。

このバグはVisual Studio 2010で修正されています。

0
Ben Challenor

これは実際にはコンパイラエラーです。

私も同じ問題を抱えていましたが、プロジェクトをクリーンアップして再構築するだけで解決しました。その後、問題は消えました。

0
DOHXEHAPO

1つの解決策は、ReSharperコードを使用する部分クラスにすべてのコードを移動することです。そこでは、ReSharper名前空間のみをインポートし、System.Coreはインポートしません。

残りの部分クラスでは、System.Coreを含め、必要な他のすべての名前空間をインポートしますが、ReSharper名前空間はインポートしません。

0
Fabrice