【问题标题】:Are there any workarounds for the lack of assignment operator overloading in c#?c#中缺少赋值运算符重载有什么解决方法吗?
【发布时间】:2016-05-13 10:42:16
【问题描述】:

我有一个库,我正在尝试从 c++ 移植到 c#。该库提供了一个类,该类应该是数字类型的直接替代品,因此可以在不大量重写代码的情况下使用它。这在 c++ 中是相当微不足道的,但我坚持在 c# 中缺少赋值运算符重载。我想要一个类似的类或结构:

public struct Number<T>
{
    private T value;
    private int importantInteger;

    public  Number(T initialValue, int initialInteger = 0)
    {
        value = initialValue;
        importantInteger = initialInteger;
    }

    public static implicit operator Number<T>(T initialValue)
    {
        return new Number<T> (initialValue);
    }

    public static implicit operator T(Number<T> number)
    {
        return number.value;
    }
    public override string ToString ()
    {
        return value.ToString() + "    " + importantInteger.ToString();
    }
}

但在更新时具有importantInteger 值的持久内存。如果我这样做:

var n = new Number<int>(23, 5);
n = 3*n;
Console.WriteLine(n.ToString());

然后我可以看到importantInteger 等于0,因为n = 3*n; 正在创建一个默认值为importantInteger 的新Number&lt;int&gt; 对象。我希望现有对象仅更新 value,以便 importantInteger 保持不变,但至少我希望将其复制到新对象。

有什么办法可以远程完成这样的事情吗?我已经阅读了许多类似的问题,并且我很清楚我不能重载赋值运算符。有没有什么优雅的方式来获得类似的行为呢?我真的需要让用户每次想要更新它的价值时都做类似n = Number&lt;int&gt;(3*n, n.importantInteger); 的事情吗?对于图书馆的用户来说,这似乎既低效又不必要的复杂/丑陋。我真的很想听听一些可行的替代方案,它们是惯用的、更优雅的。

【问题讨论】:

  • 无法通过重载赋值运算符来解决这个问题。当您尝试分配值时,当您通过隐式运算符将对象转换为int 时,您尝试使用的整数已经丢失。解决问题的唯一方法是重载* 运算符(或使用方法代替该运算符)。

标签: c# operator-overloading assignment-operator


【解决方案1】:

为什么不重载数学运算符呢?

public static Number<T> operator*(Number<T> value, Number<T> otherValue)
{
    //Do your operation on otherValue here so that it is what you want
    return otherValue;
}

我不确定你的importantInteger 需要如何在这里计算,但如果你还为T 创建了一个隐式转换运算符到Number&lt;T&gt;,这应该可以工作。

跟进您的评论。即使你不能在泛型上使用算术运算符,你也可以这样做:

if(typeof(T) == typeof(int))
{
    //cast values to ints and do the math.
}
else if(typeof(T) == typeof(double))
    //do double version

等等。有点乏味,但它会完成工作。

【讨论】:

  • 我非常愿意这样做,但您不能将代数运算符与泛型一起使用,因为没有编译时保证它们在运行时可用。数值泛型的类型约束将非常有用,但在 c# 中缺少。有一些非常复杂的解决方法,但即使有了这些,用户仍然可以很容易地执行像 n = 1; 这样的直接分配并破坏状态。
  • @Ivanna 如果您必须拥有这些属性,那么您将无法使用泛型。就是这么简单。
  • @Servy 这与我最初的问题有点相干,但这就是我所指的:jonskeet.uk/csharp/genericoperators.html
  • @Ivanna 我刚刚编辑了我的答案,以解决您如何具体处理这个问题。有点乏味,但数字类型并不多。
  • @pquest 这仍然会从解决方案中删除所有静态类型。如果静态类型对您很重要,唯一的解决方案是为每个数字类型创建一个包装器。
猜你喜欢
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 2013-03-30
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多