标签: operator-overloading

C#中基于接口的编程的运算符重载

背景

我在当前项目中使用基于接口的编程,并在重载运算符(特别是Equality和Inequality运算符)时遇到问题.


假设

  • 我正在使用C#3.0,.NET 3.5和Visual Studio 2008

更新 - 以下假设是错误的!

  • 要求所有比较使用Equals而不是operator ==不是一个可行的解决方案,尤其是在将类型传递给库(例如Collections)时.

我担心要求使用Equals而不是operator ==的原因是我在.NET指南中找不到任何地方,它声称它会使用Equals而不是operator ==甚至建议它.但是,重新阅读覆盖等于和操作员指南==我发现了这个:

默认情况下,operator ==通过确定两个引用是否指示同一对象来测试引用相等性.因此,引用类型不必实现operator ==以获得此功能.当一个类型是不可变的,也就是说,实例中包含的数据不能改变时,重载operator ==来比较值的相等而不是引用相等可能是有用的,因为作为不可变对象,它们可以被认为是相同的因为它们具有相同的价值.在非不可变类型中覆盖operator ==不是一个好主意.

和这个Equatable接口

当在Contains,IndexOf,LastIndexOf和Remove等方法中测试相等性时,IEquatable接口由泛型集合对象(如Dictionary,List和LinkedList)使用.它应该针对可能存储在泛型集合中的任何对象实现.


约束上

  • 任何解决方案都不能要求将对象从其接口转换为其具体类型.

问题

  • 当operator ==的两边都是接口时,底层具体类型的operator == overload方法签名都不匹配,因此将调用默认的Object operator ==方法.
  • 在类上重载运算符时,二元运算符的至少一个参数必须是包含类型,否则会生成编译器错误(错误BC33021 http://msdn.microsoft.com/en-us/library/watt39ff .aspx)
  • 无法在接口上指定实现

请参阅下面的代码和输出,以说明问题.


在使用基于接口的编程时,如何为类提供适当的操作符重载?


参考

==运算符(C#参考)

对于预定义的值类型,如果操作数的值相等,则相等运算符(==)返回true,否则返回false.对于除string之外的引用类型,如果其两个操作数引用同一对象,则==返回true.对于字符串类型,==比较字符串的值.


也可以看看


using System;

namespace OperatorOverloadsWithInterfaces
{
    public interface IAddress : IEquatable<IAddress>
    {
        string StreetName { get; set; }
        string City { get; set; }
        string State { get; set; }
    }

    public …
Run Code Online (Sandbox Code Playgroud)

.net c# equals operator-overloading

72
推荐指数
1
解决办法
2万
查看次数

如何在C++中重载一元减运算符?

我正在实现向量类,我需要得到一些向量的反面.是否可以使用运算符重载定义此方法?

这就是我的意思:

Vector2f vector1 = -vector2;
Run Code Online (Sandbox Code Playgroud)

这就是我希望这个运算符完成的事情:

Vector2f& oppositeVector(const Vector2f &_vector)
{
 x = -_vector.getX();
 y = -_vector.getY();

 return *this;
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

c++ operator-overloading

69
推荐指数
2
解决办法
5万
查看次数

在JavaScript中重载算术运算符?

考虑到这个JavaScript"类"定义,这是我能想到的最好的方法来解决这个问题:

var Quota = function(hours, minutes, seconds){
    if (arguments.length === 3) {
        this.hours = hours;
        this.minutes = minutes;
        this.seconds = seconds;

        this.totalMilliseconds = Math.floor((hours * 3600000)) + Math.floor((minutes * 60000)) + Math.floor((seconds * 1000));
    }
    else if (arguments.length === 1) {
        this.totalMilliseconds = hours;

        this.hours = Math.floor(this.totalMilliseconds / 3600000);
        this.minutes = Math.floor((this.totalMilliseconds % 3600000) / 60000);
        this.seconds = Math.floor(((this.totalMilliseconds % 3600000) % 60000) / 1000);
    }

    this.padL = function(val){
        return (val.toString().length === 1) ? "0" + val : val;
    }; …
Run Code Online (Sandbox Code Playgroud)

javascript operator-overloading

68
推荐指数
8
解决办法
6万
查看次数

有什么正当理由使一元运算符超载?

好吧,我受到启发,做了一些冲击.似乎超载operator&导致了不小的痛苦.

重载它有哪些合法案例?

(不能说我曾经那样做过......)

c++ operator-overloading

68
推荐指数
5
解决办法
3819
查看次数

De Morgan的Law优化与重载运算符

每个程序员都应该知道:

德摩根1
德摩根2
(德摩根定律)

在某些情况下,为了优化程序,编译器可能会修改(!p && !q)(!(p || q)).

这两个表达式是等价的,并且评估第一个或第二个没有区别.
但是在C++中,可能会重载运算符,而重载的运算符可能并不总是尊重这个属性.因此,以这种方式转换代码实际上将修改代码.

如果编译器使用德摩根定律时!,||&&超载?

c++ operator-overloading compiler-optimization language-lawyer

67
推荐指数
4
解决办法
3654
查看次数

虚拟赋值运算符C++

C++中的赋值运算符可以是虚拟的.为什么需要它?我们可以让其他运营商也虚拟化吗?

c++ virtual virtual-functions operator-overloading

66
推荐指数
5
解决办法
6万
查看次数

何时超载逗号运算符?

我经常看到关于在C++中重载逗号运算符的问题(主要与重载本身无关,但是像序列点的概念一样),这让我想知道:

你什么时候应该重写逗号?它的实际用途有哪些例子?

我只是想不出任何我已经看到或需要的东西

foo, bar;
Run Code Online (Sandbox Code Playgroud)

在现实世界的代码中,所以我很好奇何时(如果有的话)实际使用它.

c++ function operator-overloading

64
推荐指数
10
解决办法
2万
查看次数

为什么要替换默认的new和delete运算符?

为什么一个会替换默认的操作newdelete使用自定义newdelete运营商?

这是继续重载新的和删除在非常有启发性的C++ FAQ:
运算符重载.

本FAQ的后续条目是:
我应该如何编写符合ISO C++标准的自定义newdelete运算符?

注意:答案基于Scott Meyers的"更有效的C++"课程.
(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)

c++ operator-overloading c++-faq new-operator delete-operator

64
推荐指数
4
解决办法
2万
查看次数

为什么复制赋值运算符必须返回引用/ const引用?

在C++中,我不清楚从复制赋值运算符返回引用的概念.为什么复制赋值运算符不能返回新对象的副本?另外,如果我上课A,还有以下内容:

A a1(param);
A a2 = a1;
A a3;

a3 = a2; //<--- this is the problematic line
Run Code Online (Sandbox Code Playgroud)

operator=定义如下:

A A::operator=(const A& a)
{
    if (this == &a)
    {
        return *this;
    }
    param = a.param;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading copy-constructor assignment-operator

62
推荐指数
4
解决办法
4万
查看次数

我应该如何编写符合ISO C++标准的自定义新的和删除操作符?

我应该如何编写符合ISO C++标准的自定义newdelete运算符?

这是在延续重载new和delete在非常照明C++ FAQ,操作符重载,以及其后续,一个为什么要更换默认的new和delete操作?

第1部分:编写符合标准的new运算符

第2节:编写符合标准的delete运算符

(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法首先开始,所以你的答案很可能被那些提出想法的人阅读.)
注意:答案是基于Scott Meyers的学习'更有效的C++和ISO C++标准.

c++ operator-overloading c++-faq new-operator delete-operator

62
推荐指数
4
解决办法
1万
查看次数