4

Webサービスのリクエストオブジェクトを作成するには、いくつかの配列にアイテムを動的に追加する必要があります。

拡張メソッドを実装することで、それを単純化したいと思いました。

public static class ArrayExtensions<T> where T : class
{
    public static T[] Extend<T>(T[] originalArray, T addItem)
    {
        if (addItem == null)
        {
            throw new ArgumentNullException("addItem");
        }
        var arr = new[] { addItem };
        if (originalArray == null)
        {
            return arr;
        }
        return originalArray.Concat(arr).ToArray();
    }
}

そのため、この古いコードは次のようになります。

if (foo.bazArr == null)
{
    foo.bazArr  = new[] { baz };
}
else
{
    foo.bazArr = new[] { baz }.Concat(foo.bazArr).ToArray(); // (i know this inserts the new item at the beginning, but that's irrelevant, order doesn't matter)
}

次のように書き直すことができます:

foo.bazArr = foo.bazArr.Extend(baz); // won't compile

エラーは次のとおりです。'System.Array' does not contain a definition for 'Extend' and no extension method 'Extend' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)

そのように直接extensionメソッドを呼び出すのに対して:

foo.bazArr = ArrayExtensions<someService.bazType>.Extend(foo.bazArr, baz);

正常にコンパイルされます。

どうしてこんなことに?配列が強く型付けされている場合、コンパイラがここで型を推測できないのはなぜですか?


編集-以下の正しいコード:

public static class ArrayExtensions
{
    public static T[] Extend<T>(this T[] originalArray, T addItem) where T : class
    {
        if (addItem == null)
        {
            throw new ArgumentNullException("addItem");
        }
        var arr = new[] { addItem };
        if (originalArray == null)
        {
            return arr;
        }
        return originalArray.Concat(arr).ToArray(); // although Concat is not recommended for performance reasons, see the accepted answer
    }
}

このよくある質問について、もう1つの簡単な例を示します。

public static class Extns
    {
    // here's an unbelievably useful array handling extension for games!

    public static T AnyOne<T>(this T[] ra) where T:class
        {
        int k = ra.Length;
        int r = Random.Range(0,k);
        return ra[r];
        // (add your own check, alerts, etc, to this example code)
        }
    }

と使用中..

someArrayOfSoundEffects.AnyOne().Play();
someArrayOfAnimations.AnyOne().BlendLeft();
winningDisplay.text = successStringsArray.AnyOne() +", " +playerName;
SpawnEnormousRobotAt( possibleSafeLocations.AnyOne() );

等々。どの配列でも、ランダムなアイテムが1つ与えられます。効果などをランダム化するためにゲームで常に使用されます。配列は任意のタイプにすることができます。

4

3 に答える 3

6

行方不明this

public static T[] Extend<T>(this T[] originalArray, T addItem)

それがなければ、this 拡張メソッドではありません

追記:配列を一度に1つのアイテムに拡張すると、コストがかかります。AList<T>がはるかに望ましいでしょう。Webサービスツールがオプションとしてリストを提供しているかどうかを確認してください。

配列を使用する場合でも、ここで使用するのEnumerable.Concatはおそらくやり過ぎです。2つの配列を測定し、新しい配列を割り当て、CopyToそれぞれのメソッドを使用して新しい配列に書き込みます。

于 2012-05-14T06:53:16.720 に答える
2

this拡張メソッドの定義に使用

public static T[] Extend<T>(this T[] originalArray, T addItem)
于 2012-05-14T06:53:54.147 に答える
1

「this」キーワードを見逃しました

于 2012-05-14T06:53:57.660 に答える