0

私は2つの配列を持っています、smallArrayそしてbigArray、例えば

 void myFun(TypeA a, TypeA b, TypeA c, TypeA d)
 {
      TypeA[] smallArray = new TypeA[]{a,b,c,d}
      TypeA[] bigArray = new TypeA[]{a,b,a,b,c,c,c,d,d,a,c,b,d,a,d,...}
 }

bigArrayからのメンバーのみが含まれsmallArrayます。bigArrayここで、 内のすべてのオブジェクトを交換しますが、構造上の順序を維持し、操作の数を最小限に抑えたいと考えています。

たとえば、私の理想的な結果は、 ... の新しいオブジェクトが{aa,bb,aa,bb,cc,cc,cc,dd,dd,aa,cc,bb,dd,aa,dd,...}どこにあるかということです。aaTypeA

したがって、コードを次のように再設計します。

class TypeB
{
    public TypeA Value {get; set;}
}

void myFun(TypeB a2, TypeB b2, TypeB c2, TypeB d2) // where a2.Value = a, b2.Value = b...
{
    TypeB[] smallArray = new TypeB[]{a2,b2,c2,d2}
    TypeB[] bigArray = new TypeB[]{a2,b2,a2,b2,c2,c2,c2,d2,d2,a2,c2,b2,d2,a2,d2,...}
}

ターゲット オブジェクトをラッパーに「ボックス化」し、ラップされたオブジェクトを配列に格納します。のオブジェクトの値を更新するとsmallArray、 のメンバーの値bigArrayも同時に更新されます。

この技術は一般的に使用されていますか?またはそれを単純化する他の方法はありますか?

アップデート

これで、少なくとも質問を理解できるようにTypeAなります。string

私は2つの配列を持っています、smallArrayそしてbigArray、例えば

string[] smallArray = new string[] {"a","b","c","d"}
string[] bigArray = new string[] {"a","b","a","b","c","c","c","d","d","a","c","b","d","a","d",...}

bigArrayからのメンバーのみが含まれsmallArrayます。bigArrayここで、 内のすべてのオブジェクトを交換しますが、構造上の順序を維持し、操作の数を最小限に抑えたいと考えています。

たとえば、私の理想的な新しい bigArry は次のようになります。{"aa","bb","aa","bb","cc","cc","cc","dd","dd","aa","cc","bb","dd","aa","dd",...}

したがって、コードを次のように再設計します。

class TypeB
{
    public string Value {get; set;}
}

void myFun(TypeB a2, TypeB b2, TypeB c2, TypeB d2) // where a2.Value = "a", b2.Value = "b"...
{
    TypeB[] smallArray = new TypeB[]{a2,b2,c2,d2}
    TypeB[] bigArray = new TypeB[]{a2,b2,a2,b2,c2,c2,c2,d2,d2,a2,c2,b2,d2,a2,d2,...}
}

をラッパーに「ボックス化」stringし、ラップされたオブジェクトを配列に格納します。のオブジェクトの値を更新するとsmallArray、 のメンバーの値bigArrayも同時に更新されます。

したがって、例では、全体ではなく 4 つのオブジェクトのみを更新する必要がありますbigArray

この技術は一般的に使用されていますか?またはそれを単純化する他の方法はありますか?

4

3 に答える 3

2

基本的に、その答えは「はい、できます」です。もっと簡単な方法は、bigArray を int 型にして、単にインデックスを smallArray に格納することです。

TypeB[] smallArray = new TypeB[] { a2, b2, c2, d2 };
int[] bigArray = new int[] { 0, 1, 0, 1, 2, 2, 2, 2, 3, 3, 0, 2, 1, 3, 1, 3 };

このように、bigArray のレベルの間接性は同じままですが、smallArray の間接性はありません。さらに、これにより、bigArray に smallArray にない要素が含まれないようになります (範囲外のインデックスを除く)。

さらに詳しく説明できるようにするには、ユース ケースの詳細な説明を提供する必要があります。アプリケーションのパフォーマンスが重要ですか? メモリ制約はどうですか?

于 2012-10-04T11:33:18.433 に答える
1

はい。すべてのリストまたは配列にはポインターが格納されます。これらのポインターを一般的に知られている場所、つまりメモリ内に保持されているオブジェクトのプロパティにポイントすると、これがシングルトンとして保持されているか、配列または静的変数に保持されているかに関係なく、「ラップされた」オブジェクトを次の場所で交換できます。中心的な場所。適切な例がなければ、これは一般的に使用される慣行ではありませんが、これを行う適切な状況があることは想像できます。

于 2012-10-04T11:32:45.610 に答える
0

参照型を宣言すると、

 class SomeClass
 {
 }

次に、それに変数をインスタンス化します。

 var someInstance = new SomeClass()

次に、このような別の変数を宣言します。

 var someInstance2 = someInstance

メモリ内のインスタンスは1つだけですSomeClassが、2つの変数がsomeInstanceありsomeInstance2、そのSomeClassインスタンスを参照またはポイントしています。


したがって、の2つの新しいインスタンスを宣言する場合は、キーワードにSomeClass注意してください。new

var a = new SomeClass();
var b = new SomeClass();

次に、それらを使用して2つの新しいアレイを初期化します

var smallArray = new SomeClass[] { a, b }
var bigArray = new SomeClass[] { a, b, a, a, b, b, b, a }

の2つの新しいインスタンスのみをインスタンス化しSomeClassました。合計10個の参照またはポインターを含むが、追加のSomeClass参照を含まない2つの新しい配列を作成しました。

参照型の新しいインスタンスが作成されるのは、newキーワードが使用されたときだけです(いくつかの無関係な例外があります)。これは役に立ちますか?


したがって、配列のすべてのメンバーを他のメンバーに置き換えたい場合は、次のような関数を作成できます。

public static class ArrayExtension
{
    void Substitute<T>(this T[] array, IDictionary<T, T> subsitute)
    {
         for (var i = 0; i < array.Length; i++)
         {
              if (substitute.ContainsKey(array[i])
              {
                  array[i] = substitute[array[i]];   
              }
         }
    } 
}

私はこのように呼ぶことができます、

var substitutes = new Dictionary
    {
        { Key = a, Value = aa },
        { Key = b, Value = bb },
        { Key = c, Value = cc },
        { Key = d, Value = dd }
    }

bigArray.Substitute(substitutes);
于 2012-10-04T11:31:08.260 に答える