4

さまざまなFuncデリゲートのオーバーロードがある関数で匿名メソッドを使用すると、VisualStudio2010で奇妙な動作に遭遇しました。

以下に小さな複製クラスを作成しました。

このListViewAdapterクラスを検討してください

namespace LambdaTestApp
{
    public class ListViewAdapter<T>
    {
        private Func<int, string, int, string> _converter1;
        private Func<RefType1, string, string> _converter2;

        public ListViewAdapter(int arg1, Func<int, string, int, string> converter) 
        {
            _converter1 = converter;
        }

        public ListViewAdapter(int arg1, Func<RefType1, string, string> converter) 
        {
            _converter2 = converter;
        }

        public static ListViewAdapter<T> MockPopulate(int arg, Func<int, string, int, string> converter) {

            ListViewAdapter<T> instance = new ListViewAdapter<T>(arg, converter);

            return instance;
        }

        public static ListViewAdapter<T> MockPopulate(int arg, Func<RefType1, string, string> converter)
        {
            ListViewAdapter<T> instance = new ListViewAdapter<T>(arg, converter);
            return instance;
        }
    }

    public class RefType1
    {
        public string Property1 { get; set; }
    }
}

そして、ラムダでオーバーロードを使用する次のコード:

namespace LambdaTestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ListViewAdapter<RefType1>.MockPopulate(1, (item, str) =>
            {
                var myItem = item;
                return str;
            });
        }
    }
}

解決する必要がFunc<RefType1, string, string>あり、最初の引数はである必要がありますが、問題は、 Visual StudioRefType1である代わりに、それを。と見なすということです。itemRefType1int

質問:Funcデリゲート間には明らかではない有効な変換がありますか、それともこれはVisual Studio IntelliSenseのバグですか?

4

3 に答える 3

5

私はそれがバグであるか、少なくとも欠陥であることに個人的に同意します。コードが無効な場合にのみ表示され、ラムダ式内のコードが無効な場合にのみ表示されますが、Intellisenseは、ラムダ式のパラメーター宣言部分(前の部分=>)を次のように表示する方が適切だと思います。完了し、その情報に基づいて作業します。

有効な選択を行う方法でオーバーロードの解決を変更するラムダ式の本体に入れることができるものは何もありませんFunc<int, string, int, string>...十分なパラメーターがないだけです。

少なくとも、これに関するConnectの問題をログに記録することをお勧めします。「MSはこのシナリオに対応するように設計していません」という点では「意図したとおりに機能している」可能性がありますが、明らかにうまく機能する可能性があります。確かに、現在実行しているラップトップはベータ版に最近の更新を適用していませんが、VS11ベータ版ではまだこのように機能していることに注意してください。「はい、それはいいのですが、少しの利益のために膨大な量の作業が必要です」という応答があったとしても、私は驚かないでしょうが、とにかく、IMOを上げる価値があります。

于 2012-04-14T08:32:21.210 に答える
2

解決する必要がFunc<RefType1, string, string>あり、最初の引数はである必要がありますRefType1が、問題は、アイテムがRefType1Visual Studioである代わりに、それを。として認識することintです。

Visual Studioは、オーバーロードされた関数の最初のものを調べることにより、コンパイルエラーがある限りそれを推測します。intコードを理解できないため、どのオーバーロードが使用されているかを判別できません。おそらくどちらを意味するのかを推測することでより良い仕事をすることができるかもしれませんが、これをバグと考えるのは少し厳しいです。

エラーを修正すると、VisualStudioは引数の種類が。であることを認識できますRefType1。これを確認するには、コードがコンパイルされていることを確認してから、マウスをに置きますitem

はい、残念ながら、これは、入力.すると少なくとも一時的にコードが無効になり、のメンバーが表示されることを意味しますint。本当に必要な場合はitem.ToString();、コンパイラーが満足する方法で呼び出してから、.を新しいで上書きできます.。次に、希望するリストが表示されます。

または、Visual Studioの推測を変えるために、最も一般的に使用されるオーバーロードが最初にリストされていることを確認してください。

于 2012-04-12T19:12:14.670 に答える
0

LINQのメソッドのオーバーロード解決は、C#の場合とまったく同じように機能します。引数の数とタイプに基づいており、それ以上のことはありません。引数が一般的であるかどうかは関係ありません。

のコードを見ずにPopulateListView、intを渡していると言わざるを得ません。それが、あなたが得ているものです。

于 2012-03-30T18:39:59.603 に答える