Luați în considerare abstractizarea accesului la date cu un Proxy (similar cu iteratorii/indicatorii inteligenți în C ++) . Din păcate, sintaxa nu este la fel de curată ca C ++ ca operatorul (), care nu este disponibil pentru suprasarcină, iar operatorul [] este un singur arg, dar încă aproape.
Desigur, acest nivel suplimentar de abstractizare adaugă complexitatea și activitatea proprie, dar vă va permite să efectuați modificări minime ale codului existent care utilizează obiecte duble [], permițându-vă să folosiți o singură matrice dublă [] pentru ambele interop și calculul dvs. în C #.
class Matrix3
{
//referece-to-element object
public struct Matrix3Elem{
private Matrix3Impl impl;
private uint dim0, dim1, dim2;
//other constructors
Matrix3Elem(Matrix3Impl impl_, uint dim0_, uint dim1_, uint dim2_) {
impl = impl_; dim0 = dim0_; dim1 = dim1_; dim2 = dim2_;
}
public double Value{
get { return impl.GetAt(dim0,dim1,dim2); }
set { impl.SetAt(dim0, dim1, dim2, value); }
}
}
//implementation object
internal class Matrix3Impl
{
private double[] data;
uint dsize0, dsize1, dsize2;//dimension sizes
//.. Resize()
public double GetAt(uint dim0, uint dim1, uint dim2) {
//.. check bounds
return data[ (dim2 * dsize1 + dim1) * dsize0 + dim0 ];
}
public void SetAt(uint dim0, uint dim1, uint dim2, double value) {
//.. check bounds
data[ (dim2 * dsize1 + dim1) * dsize0 + dim0 ] = value;
}
}
private Matrix3Impl impl;
public Matrix3Elem Elem(uint dim0, uint dim1, uint dim2){
return new Matrix2Elem(dim0, dim1, dim2);
}
//.. Resize
//.. GetLength0(), GetLength1(), GetLength1()
}
Apoi, folosind acest tip atât pentru citire cât și pentru scriere - "foo [1,2,3]" este acum scris ca "foo.Elem (1,2,3) .Value", atât în valorile citirii, cât și în valorile de scriere, pe partea stângă a expresiilor de atribuire și valori.
void normalize(Matrix3 m){
double s = 0;
for (i = 0; i < input.GetLength0; i++)
for (j = 0; j < input.GetLength(1); j++)
for (k = 0; k < input.GetLength(2); k++)
{
s += m.Elem(i,j,k).Value;
}
for (i = 0; i < input.GetLength0; i++)
for (j = 0; j < input.GetLength(1); j++)
for (k = 0; k < input.GetLength(2); k++)
{
m.Elem(i,j,k).Value /= s;
}
}
Din nou, au fost adăugate costuri de dezvoltare, dar au fost împărțite date, eliminându-se cheltuielile generale de copiere și costurile de dezvoltare aferente. E un compromis.