【问题标题】:Override objects return value覆盖对象返回值
【发布时间】:2014-01-29 08:42:03
【问题描述】:

我正在尝试将一个对象与一个 int 值进行比较,例如

if (myObject - 5 == 0)
    doSomething();

我的类可能看起来像这样:(删除了大多数 setter/getter,所以不要介意所有变量都是私有的)

public class SomeClass
{
    public string name;
    private int minValue;
    private int maxValue;
    private int currValue;

    public int getCurrentValue()
    {
        return currValue;
    }
}

我想要实现的是这样的:

someClassInstance - 5;

平等

someClassInstance.getCurrentValue() - 5;

我可以将对象重写为一个 int(它自己的变量)而不是仅仅作为一个对象吗?

【问题讨论】:

  • @TimSchmelter,谢谢!
  • Dmitry 在下面的回答非常好,但问问自己使用这样的一元运算符是否有意义。例如:“myCar + hisCar”会让人难以理解正在执行的操作。
  • Dmitry Bychenko 的回答让我大吃一惊,但我更喜欢 Matthew Watson,因为它在性能方面似乎更有效率。
  • 我不认为这个问题应该被关闭,因为 @Matthew Watson 的答案在其他答案中不可用。

标签: c#


【解决方案1】:

运营商可能是这样吗?

public class SomeClass {
  ...

  public static int operator -(SomeClass left, int right) {
    if (Object.ReferenceEquals(null, left))
      throw new ArgumentNullException("left");

    return left.getCurrentValue() - right;
  }
}

...

SomeClass someClassInstance = new SomeClass(...);

int result = someClassInstance - 5;

另一种可能性(基于隐式运算符)是在需要时 SomeClass 隐式转换为int

public class SomeClass {
  ...

  // Whenever int is requiered, but SomeClass exists make a conversion
  public static implicit operator int(SomeClass value) {
    if (Object.ReferenceEquals(null, value))
      throw new ArgumentNullException("value");

    return value.getCurrentValue();
  }
}

...

SomeClass someClassInstance = new SomeClass(...);

int result = someClassInstance - 5;

【讨论】:

  • +1 值得注意的是,他应该更好地使用不可变值类型,因此使用struct 而不是类。引用 E.Lipper 的话:“这正是不可变值类型的设计目的”
  • 作为一个问题,这是否适用于 int 转换运算符重载: int result = 5 - classInstance; ?
  • 谢谢,您的回答很有帮助!
  • @besworland: "int result = 5 - classInstance" 不能与 "-" 运算符一起使用(除了现有的一个参数之外,您还应该实现 "int operator -(int left, SomeClass right)"订单事项);但它适用于隐式运算符
【解决方案2】:

实际上你最好重写operator int,这样你就可以用更少的重载进行更多的计算:

using System;

namespace Demo
{
    public class SomeClass
    {
        public string name;
        private int minValue;
        private int maxValue;
        public int currValue;

        public int getCurrentValue()
        {
            return currValue;
        }

        public static implicit operator int(SomeClass value)
        {
            if (value == null)
                throw new ArgumentNullException("value");

            return value.currValue;
        }
    }

    internal class Program
    {
        private void run()
        {
            var test = new SomeClass {currValue = 5};

            if (test - 5 == 0)
                Console.WriteLine("It worked");

            if (test + 5 == 10)
                Console.WriteLine("This also worked");
        }

        private static void Main()
        {
            new Program().run();
        }
    }
}

【讨论】:

  • 这个似乎更好,然后是运算符 - 重载!酷,学习新东西总是好的! :)
  • 你必须小心隐式转换 - 你可能会不小心将一些东西传递给一个需要 int 的方法,它会默默地为你转换它。如果您不想要这种行为,您可以将implicit 更改为explicit,然后您必须将显式转换添加到int
【解决方案3】:

您可以尝试混合使用 implicit conversionsoperator overloading,但根据我的经验,您永远无法让它像您希望的那样无缝运行(并且您可以让它在 C++ 中运行)。

如果我是你,我会将 getCurrentValue 更改为属性:

public int CurrentValue
{
    get {return currValue};
}

只需使用someClassInstance.CurrentValue -5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多