2

次のコードを検討してください。

using System.Collections.Generic;
namespace TestingTypes
{
    class Program
    {
        static void Main(string[] args)
        {
            var strings = new List<string>();               
            INeedToPassThisMethodAListOfObjects(strings as List<object>);
        }

        static void INeedToPassThisMethodAListOfObjects(List<object> objects) { }
    }
}

1>------ Build started: Project: TestingTypes, Configuration: Debug Any CPU ------
1>c:\users\[censored]\TestingTypes\Program.cs(9,41,9,64): error CS0039: Cannot convert 
type 'System.Collections.Generic.List<string>' to 
'System.Collections.Generic.List<object>' via a reference conversion, boxing 
conversion, unboxing conversion, wrapping conversion, or null type conversion

文字列はオブジェクトであり、C# 4 はジェネリック型の共変性をサポートするはずなので、List<string>List<object> であると言うかもしれません。

  • 型を変換できないとコンパイラが言うのはなぜですか?
  • メソッドに「文字列」を渡すにはどうすればよいですか?
4

3 に答える 3

3

List<string>a が aではないため、エラーが発生していますList<object>

list.Add(new TextBox())電話をかけることはできますList<object>が、明らかに、同じ電話は では機能しませんList<string>

C# ジェネリックは、ジェネリック型が不変の場合にのみ共分散を許可します (これは、List から IEnumerable へのキャストが機能する場合です)。

リストをメソッドに渡す必要がある場合は、渡してみてください

listOfStrings.Cast<object>();

欠点としては、このソリューションを使用すると、メソッド呼び出し内でリストに加えられた変更が元のリストに反映されません (呼び出しCastによって新しいリストが作成されるため)。

メソッドを制御でき、INeedToPassThisMethodAListOfObjectsそのメソッドがコレクションを変更するのではなく、コレクションを反復処理するだけでよい場合は、パラメーターの型を に変更できます。その場合、問題なくIEnumerable<object>を渡すことができます。List<string>

于 2012-10-24T17:04:54.660 に答える
3

インターフェイスはバリアントにすることができます。クラスはできません。解説はこちらをご覧ください。

stringsコレクションをキャストせずに渡し、宣言を次のように変更すると、コードが機能します。

static void INeedToPassThisMethodAListOfObjects(IEnumerable<object> objects) { }

Listただし、それは、この関数内でが必要かどうかによって異なります。

于 2012-10-24T17:08:07.423 に答える
2

文字列をオブジェクトに変換する必要があります。そうするための素敵なLINQメソッドがあります。

var strings = new List<string>();               
INeedToPassThisMethodAListOfObjects(strings.Cast<object>());

編集

あなた自身のリンクによると、

C# では、次のシナリオでバリアンスがサポートされます。

  • 配列の共分散 (C# 1.0 以降)

  • デリゲートの共分散と反分散。「メソッド グループ分散」とも呼ばれます (C# 2.0 以降)。

  • インターフェイスとデリゲートのジェネリック型パラメーターの差異 (C# 4.0 以降)

したがって、IEnumerable は List を受け入れます。

于 2012-10-24T17:06:29.003 に答える