Я должен признать, что я абсолютно новичок в деревьях выражений в C #, но в настоящее время есть необходимость привыкнуть к нему. Моя проблема в том, что у меня есть два типа данных, которые содержат массив массивов. По этой причине я создал интерфейс, который называется IArray <>
/// <summary>
/// Interface for all classes that provide a list of IArrayData
/// </summary>
public interface IArray<ElementDataType>
where ElementDataType : struct
{
/// <summary>
/// Returns a single data out fo the array container.
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
IArrayData<ElementDataType> GetElementData(int index);
/// <summary>
/// Returns the amount of ArrayData.
/// </summary>
int Count
{
get;
}
/// <summary>
/// Returns the size of a single dataset in number of elements
/// (not in bytes!).
/// </summary>
/// <returns></returns>
int GetDataSize();
/// <summary>
/// Creates a copy of the array data provider, by copying the metainformation, but not the
/// contents.
/// </summary>
/// <returns></returns>
IArray<ElementDataType> CloneStub();
}
IArrayData определяется следующим образом:
/// <summary>
/// DataProvider that provides the internal data as an array.
/// </summary>
/// <typeparam name="NativeDataType"></typeparam>
public interface IArrayData<NativeDataType> where NativeDataType : struct
{
/// <summary>
/// Returns the data in an arbitrary format.
/// The implementor must take care of an appropriate cast.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T[] GetData<T>() where T : struct;
/// <summary>
/// Returns the data as float[].
/// </summary>
/// <returns></returns>
float[] GetData();
/// <summary>
/// Sets the data in an arbitrary format.
/// The implementor must take care of an appropriate cast.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data_in"></param>
void SetData<T>(T[] data_in) where T : struct;
/// <summary>
/// Sets the data as float[].
/// </summary>
/// <param name="data_in"></param>
void SetData(float[] data_in);
}
Существует два типа, которые реализуют интерфейс. На большинстве данных я должен выполнить математические операции над данными. В настоящее время я создал собственный оценщик выражений, но я бы хотел использовать деревья выражений, потому что мне кажется, что он более гибкий. Как мне реализовать математическую операцию типа +, - на данном интерфейсе?
Один тип, который у меня есть, это то, что я называю VoxelVolume, который предназначен для хранения трехмерного блока данных изображения. VoxelVolume реализует IArray:
public abstract class VoxelVolume : IArray<float>
{
}
Предположим, у меня есть 3 VoxelVolumes A, B и C. Теперь я хочу выполнить операцию:
VoxelVolume D = (A + B) * C;
В настоящее время я делаю это с перегрузкой операторов, и она работает довольно хорошо. Единственная проблема заключается в том, что выражение оценивается операция за операцией, и чем длиннее выражение, тем больше времени и памяти оно занимает. Я бы предпочел объединить операцию в один шаг. Это то, что моя текущая реализация делает
public static IArray<float> AddMul(IArray<float> A, IArray<float> B, IArray<float> C)
{
IArray<float> Result = A.CloneStub();
int L = A.Count;
int N = A.GetDataSize();
for (int l = 0; l < L; l++)
{
float[] a = A.GetElementData(l).GetData();
float[] b = B.GetElementData(l).GetData();
float[] c = C.GetElementData(l).GetData();
float[] d = new float[a.Length];
for (int n = 0; n < N; n++)
{
d[n] = (a[n] + b[n]) * c[n];
}
Result.GetElementData(l).SetData(d);
}
return Result;
}
Но, как вы можете заметить, мне приходится много печатать для всех различных операций +, -, *, / и многое другое. По этой причине я хотел бы иметь более общий и гибкий способ выполнения этих операций.
Спасибо
Martin