7

C#で次のようなことを行う方法はありますか:

public void Foo<T>()
{
    T[] arr = Goo() as T[];
}

Goo が を返す場所ではobject[]、リフレクションなどを使用していますか?

4

2 に答える 2

7

LINQ を使用できます。

public void Foo<T>()
{
    T[] arr = Goo().OfType<T>().ToArray();
}

あなたの例では、2つのタイプが正確に一致する場合にも機能する をキャストしていますobject[]:T[]

public void Foo<T>()
{
    T[] arr = Goo() as T[];
    if (arr != null)
    {
        // use the array
    }
}

たとえば、これは次の場合に機能します。

public object[] Goo()
{
    return new string[] { "a", "b" };
}

そして、次のように Foo を呼び出します。

Foo<string>();
于 2012-09-24T06:15:05.023 に答える
1

おそらく最も簡単で信頼性の高い方法は、アイテムごとにキャストして配列をコピーすることです。

public void Foo<T>()
{
    T[] arr = Array.ConvertAll(Goo(), x => (T)x);
}

これは " unbox.any" であり、(JIT に対して) 次のことを意味します。

  • 参照型であることが判明した場合は、castclass(つまり、参照保持型チェック)を実行します。T
  • 値型であることが判明したunbox場合に行うT

参照型の配列は共変です。つまり、 aはとして表すT[]ことができます。このため、 の結果実際には である可能性があります。これもテストしたいかもしれません:object[]Goo() T[]

public T[] Foo<T>()
{
    var tmp = Goo();
    T[] arr = tmp as T[];
    if(arr == null && tmp != null) {
        arr = Array.ConvertAll(Goo(), x => (T)x);
    }
    return arr;
}

ただし、これの厄介な点の 1 つは、セマンティクスが異なることです。場合によっては同じ配列であり、場合によってはコピーされます。配列を変更すると、これが問題になる可能性があります。

于 2012-09-24T06:38:31.603 に答える