简体   繁体   English

C#中是否存在类似代码同义词的内容?

[英]Is there is something like code synonyms in C#?

For example i have some code: 例如,我有一些代码:

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]));

and it seems that it is a bit dangerous. 而且似乎有点危险。 I would like to had some "code synonym", like that: 我想有一些“代码同义词”,就像那样:

var xx => myArray[i, j, k];
if (xx == someValue)
  xx = someOtherValue;
else
  throw new Exception(string.Format("value {0} is wrong!", xx));

where xx isn't a value of myArray[i, j, k] , but a synonym to that code, and => is some kind of declaration syntax for this construct. 其中xx不是myArray[i, j, k] ,而是该代码的同义词, =>是此构造的某种声明语法。

I'd like to have this feature to ensure that multiply myArray[i, j, k] usage would be exactly the same code, without risk of getting myArray[j, i, k] in some place. 我希望有这个功能,以确保乘以myArray[i, j, k]用法完全相同,没有在某个地方获得myArray[j, i, k]风险。

May be C# can do something like that, without ugly syntax? 也许C#可以做那样的事情,没有丑陋的语法? I mean safe code, not unsafe memory pointer. 我的意思是安全代码,而不是不安全的内存指针。 Or maybe something is wrong with my point of viewh? 或者我的观点可能有问题?


I apologize for possibly incorrect definition of my idea. 我为可能不正确的想法定义道歉。 I'd like to use this trick ("code synonyms" or something like that) as regular feature of language(? or compiler etc), not only in this single case. 我想使用这个技巧(“代码同义词”或类似的东西)作为语言的常规特征(?或编译器等),不仅仅是在这种情况下。 Specialized classes or functions are good in particular case, but in general they will lead to a significant increase in the amount of code, and i would like to avoid this. 特殊类或函数在特定情况下是好的,但一般来说它们会导致代码量的显着增加,我想避免这种情况。

May be use some function for this? 可能会为此使用一些功能? For example: 例如:

In your code: 在你的代码中:

UpdateElement(ref myArray[i, j, k], someValue, someOtherValue);

And function: 功能:

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: Method renaming from 'TryUpdateElement' to 'UpdateElement', because of Try.. methods usually don't throw exceptions. UPD:方法从'TryUpdateElement'重命名为'UpdateElement',因为Try ..方法通常不会抛出异常。

You could implement your own matrix type that would store an actual index 您可以实现自己的矩阵类型来存储实际索引

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;
    }
}

You can use it like this: 你可以像这样使用它:

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

The generic approach has the disadvantage that it becomes more difficult to implement numeric operations (mathematical operations like +, -, *, / are not defined on generic types). 通用方法的缺点是实现数值运算变得更加困难(如,+, - ,*,/等数学运算未在泛型类型上定义)。 But you could resolve the generic type in a dervied class, that implements numeric calculations 但是你可以在一个实现数值计算的类中解析泛型类型

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 introduced ref locals allowing you to do just that 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));

Note that you get not only a synonym but a reference, which means that the array indexes get evaluated only once. 请注意,您不仅会获得同义词而且还会获得引用,这意味着数组索引只会被评估一次。

You can use anonymous delegates for this. 您可以使用匿名委托。

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()));

That last sentence is calling for obvious responses. 最后一句话要求明显的回应。 It seems you'd like to use something like a code generator. 看起来你想使用像代码生成器这样的东西。

Something like a C preprocessor would appear to fit the bill: 像C预处理器这样的东西似乎符合要求:

#define xx myArray[i, j, k]

Well, that is indeed not the ... usual "point of view", but the good news is, you can simply use the CPP preprocessor in your C# project. 嗯,这确实不是......通常的“观点”,但好消息是,你可以简单地在你的C#项目中使用CPP预处理器。

Ideas: 思路:

  • Make it a prebuild step. 使其成为预建步骤。
  • generate your .cs from a .cs.cpp file 从.cs.cpp文件生成.cs

You could write yourself a function that allows you to do something like this: 您可以自己编写一个函数,允许您执行以下操作:

UpdateMatrixValueIf(myArray, i, j, k, (v) => v == someValue, someOtherValue);

And implement it like this: 并像这样实现它:

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]));
}

Of course doing something like this only really makes sense, if you do it more than once. 当然,如果不止一次这样做,那么做这样的事情才真正有意义。 Otherwise the answer is simply no, that you can't do it in a better or safer way. 否则答案是否定的,你不能以更好或更安全的方式做到这一点。 You could make use of some crazy reflection methods, but I don't think that would be appropriate here. 你可以使用一些疯狂的反射方法,但我认为这不合适。 Just make sure such a code section is unit tested, and you shouldn't end up with index issues. 只需确保这样的代码部分经过单元测试,您不应该最终遇到索引问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM