c#中有类似代码同义词的东西吗?
本文关键字:同义词 代码 | 更新日期: 2023-09-27 18:04:15
例如我有一些代码:
if (myArray[i, j, k] == someValue)
myArray[i, j, k] = someOtherValue;
else
throw new Exception(string.Format("value {0} is wrong!", myArray[i, j, k]));
,它似乎有点危险。我希望有一些"代码同义词",像这样:
var xx => myArray[i, j, k];
if (xx == someValue)
xx = someOtherValue;
else
throw new Exception(string.Format("value {0} is wrong!", xx));
其中xx
不是myArray[i, j, k]
的值,而是该代码的同义词,=>
是该结构的某种声明语法。
我想有这个功能,以确保乘myArray[i, j, k]
的使用将是完全相同的代码,没有风险得到myArray[j, i, k]
在某些地方。
我很抱歉我对我的想法的定义可能是错误的。我想使用这个技巧("代码同义词"或类似的东西)作为语言的常规特征(?或编译器等),不仅在这种情况下。专门化的类或函数在特定情况下是好的,但通常它们会导致代码量的显著增加,我希望避免这种情况。
可以使用一些函数吗?例如:
在你的代码中:
UpdateElement(ref myArray[i, j, k], someValue, someOtherValue);
和功能:
void UpdateElement(ref int element, int compareWith, int value)
{
if (element == compareWith)
element = value;
else
throw new Exception(string.Format("Value {0} is wrong!", element));
}
UPD:方法从'TryUpdateElement'重命名为'UpdateElement',因为Try..方法通常不会抛出异常。
您可以实现自己的矩阵类型来存储实际的索引
public class Matrix<T>
{
private T[, ,] _array;
public Matrix(int sizeX, int sizeY, int sizeZ)
{
_array = new T[sizeX, sizeY, sizeZ];
}
public T this[int i, int j, int k]
{
get { return _array[i, j, k]; }
set { _array[i, j, k] = value; }
}
public int CurrentI { get; set; }
public int CurrentJ { get; set; }
public int CurrentK { get; set; }
public void SetCurrentCell(int i, int j, int k)
{
CurrentI = i;
CurrentJ = j;
CurrentK = k;
}
public T Current
{
get { return _array[CurrentI, CurrentJ, CurrentK]; }
set { _array[CurrentI, CurrentJ, CurrentK] = value; }
}
public static implicit operator T(Matrix<T> matrix)
{
return matrix.Current;
}
// The assignment operator (=) cannot be overloaded. But we can overload |
// instead, allowing us to write: m |= value in order to perform an assignment.
public static Matrix<T> operator |(Matrix<T> m, T value)
{
m.Current = value;
return m;
}
}
你可以这样使用:
var m = new Matrix<int>(3, 3, 3);
m[0, 2, 1] = 77;
m.SetCurrentCell(0, 2, 1);
m.Current = 88;
int value = m; // Using the implicit operator and the current indexes
m |= 20; // Using |= as assignment operator
泛型方法的缺点是更难实现数值操作(泛型类型上没有定义+、-、*、/等数学操作)。但是可以在派生类中解析泛型类型,派生类实现数值计算
public class DoubleMatrix : Matrix<double> {
public static DoubleMatrix operator +(DoubleMatrix a, DoubleMatrix b)
{
//TODO: Implement + operator
return m;
}
//TODO: Implement other operators
}
c# 7.0引入了ref locals,允许你这样做
ref int xx = ref myArray[i, j, k];
if (xx == someValue)
xx = someOtherValue;
else
throw new Exception(string.Format("value {0} is wrong!", xx));
注意,您得到的不仅是同义词,还有引用,这意味着数组索引只求值一次。
您可以使用匿名委托。
var get_xx = delegate(){ return myArray[i, j, k];};
var set_xx = delegate(int v){ myArray[i, j, k] = v;};
if (get_xx() == someValue)
set_xx(someOtherValue);
else
throw new Exception(string.Format("value {0} is wrong!", get_xx()));
最后一句话需要明显的回应。看来你想使用代码生成器之类的东西。
类似C预处理器的东西似乎符合要求:
#define xx myArray[i, j, k]
嗯,那确实不是……通常的"观点",但好消息是,您可以简单地在c#项目中使用CPP预处理器。
的想法:
- 使其成为预构建步骤。
- 从。cs.cpp文件生成。cs
你可以自己写一个这样的函数:
UpdateMatrixValueIf(myArray, i, j, k, (v) => v == someValue, someOtherValue);
并像这样实现它:
public void UpdateMatrixValueIf<T>(T[,,] array, int i, int j, int k, Func<T, bool> check, T newValue)
{
if (check(array[i, j, k]))
array[i, j, k] = newValue;
else
throw new Exception(string.Format("Value {0} is wrong!", array[i, j, k]));
}
当然,做这样的事情只有在你做了不止一次的时候才有意义。否则,答案是否定的,因为你不能以更好或更安全的方式做到这一点。你可以使用一些疯狂的反射方法,但我认为在这里不合适。只要确保这样的代码段经过单元测试,就不会出现索引问题。