这种对象包装方法常用还是不好用?

时间:2012-10-04 10:53:30

标签: c#

我有2个数组,smallArraybigArray,例如

 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,...}其中aa ...是TypeA的新对象

所以我将我的代码重新设计为:

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个数组,smallArraybigArray,例如

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

这种技术常用吗?或者还有其他方法来简化它吗?

3 个答案:

答案 0 :(得分: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中的元素(除了超出范围的索引)。

为了能够说出更多内容,您应该向我们提供有关用例的更详细说明。您的应用程序性能是否严格?记忆约束怎么样?

答案 1 :(得分:1)

是。每个列表或数组都存储指针。当你把这些指针指向一个众所周知的地方时,我。即在内存中保留对象的属性中,无论是作为Singleton维护,还是在数组或静态变量中,都可以在中心位置交换“包装”对象。没有一个恰当的例子,这不是一种常用的做法,但我可以想象有合适的情况可以做到这一点。

答案 2 :(得分:0)

如果我声明了引用类型,

 class SomeClass
 {
 }

然后将变量实例化到它,

 var someInstance = new SomeClass()

然后声明另一个这样的变量,

 var someInstance2 = someInstance

内存中只有一个SomeClass实例,但我有两个变量someInstancesomeInstance2引用或指向SomeClass个实例。


因此,如果我声明了SomeClass的两个新实例,请注意new关键字,

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

然后使用它们初始化两个新数组

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

我只实例化了SomeClass的两个新实例。我创建了两个新数组,其中包含十个引用或指针的总和,但没有额外的SomeClass引用。

创建引用类型的新实例的唯一时间是使用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);