随着我在我的小数学库上的进步,我绊倒了C#和.NET Framework的某些方面,我在理解方面遇到了一些麻烦.

这次它是运算符重载,特别是术语重载本身.为什么称为重载?默认情况下,所有对象都具有所有运算符的实现吗?那就是:

public static object operator +(object o1,object o2)

在某处预定义并以某种方式?如果是这样,为什么然后如果我尝试o1 o2我得到编译时错误运算符”不能应用于’object’和’object’类型的操作数?这将以某种方式暗示默认情况下对象没有预定义的运算符,那么术语重载怎么样呢?

我问这个,因为在我的数学库中,使用3D几何元素,我有以下结构:Vector和Point.现在,在内部我想允许以下构造来创建向量:

static Vector operator -(Point p1,Point p2) {...}

由于这在数学上不是100%正确但在内部非常有用以减少代码混乱,我不想公开公开此运算符,所以我的初衷是简单地做:

internal static Vector operator -(Point p1,Point p2) {...}

令人惊讶的是(对我来说)我得到以下编译时错误:用户定义的运算符’Geometry.Vector(Geometry.Vector,Geometry.Vector)’必须声明为static和public“.

现在所有操作符必须公开的这种限制似乎对运算符的整个重载方面有一定的意义,但似乎它有点不一致:

>默认情况下,对象没有预定义的运算符:默认情况下我无法执行对象对象或myTpye myType无法事先明确定义运算符.
>定义运算符不会被描述为创建运算符,它被描述为重载,在某种程度上与第1点不一致(对我而言).
>你不能限制操作符的访问修饰符,它们必须是公共的,考虑到第1点这没有意义.但考虑到第2点,这种方式是有意义的.

有人可以用简单的术语解释我所做的这些混乱吗?

解决方法

Why is it called overloading?

它被称为“重载”,因为它正在超载.当我们为这个东西提供两个可能的实现然后必须决定使用哪个(称为重载解析)时,我们“重载”一个东西.

当我们重载方法时,我们给出两个或多个具有给定名称的方法的实现.当我们重载运算符时,我们为具有给定语法的运算符提供两个或更多可能的实现.这是同一件事.

确保您不会因重写而混淆重载.重载只是在同一个声明空间中存在两个具有相同名称/语法的方法/运算符.覆盖处理在运行时如何填充虚拟方法槽的内容.

Do all objects by default have an implementation of all operators?

没有.

Is public static object operator +(object o1,object o2) predefined somewhere and somehow?

没有.

This would somehow imply that by default objects do not have predefined operators so then how come the term overloading?

我不明白这个问题.当然C#有预定义的运算符.

I don’t want to expose this operator publicly

然后不要使用运算符;制作私人,内部或受保护的方法.

C#的设计是运算符始终是一种类型的公共表面区域的一部分.让操作符具有取决于使用的可访问域的含义是非常令人困惑的.C#经过精心设计,成为一种“质量陷阱”语言,语言设计者的选择使您远离写作混乱,越野车,难以重构的程序.要求用户定义的运算符是公共的和静态的是那些微妙的设计点之一.

(1) Objects by default do not have predefined operators

当然可以;在各种对象上有数百个预定义的运算符.例如,对于添加,运算符有以下预定义重载:

int + int
uint + uint
long + long
ulong + ulong
double + double
float + float
decimal + decimal
enum + underlying  (for any enum type)
underlying + enum
int? + int?
uint? + uint?
long? + long?
ulong? + ulong?
double? + double?
float? + float?
decimal? + decimal?
enum? + underlying?
underlying? + enum?
string + string
object + string
string + object
delegate + delegate (for any delegate type)

有关所有其他运算符的所有预定义重载的列表,请参阅C#规范.

请注意,运算符的重载决策有两个阶段:首先,重载决策尝试查找唯一最佳的用户定义的重载;只有这样做才发现没有适用的候选者是重载决议考虑的预定义重载.

(2) Defining operators is not described as creating an operator,it’s described as overloading which somehow is inconsistent (to me) with point 1.

我不明白为什么你发现它不一致,或者,就此而言,你发现不一致的东西.术语“过载”一直用于描述操作符和方法;在这两种情况下,它意味着使用相同的语法来引用两个或更多不同的东西,然后通过“重载分辨率”解决歧义.方法和运算符重载决策算法的确切细节是不同的,但它们在整个算法中是相似的:首先识别候选集,然后删除不适用的候选者,然后更好的算法消除比另一个更差的适用候选者,然后a最佳性算法确定剩下的唯一最佳候选者(如果有的话).

(3) You cannot restrict access modifier of an operator,they have to be public,which does not make sense considering point 1. but sort of makes sense considering point 2.

我不明白第(3)点与点(1)或(2)有什么关系.运算符必须成为公共表面区域一部分的限制是为了防止当你在Apple课堂内时能够为动物添加水果的混乱局面,而不是当你在班级长颈鹿中时.

Operators are declared inside a class or struct and therefore “belong” to said type,they don’t float “belonging” to no given type. So what am I overloading exactly when I declare an operator in a class?

你的操作符正在超载.

That the same operator exists between ints does not mean I am overloading anything as that operator belongs to int. To me its the same as saying the Foo.Hello() and Bar.Hello(string hello) are overloads of Hello. They are not as they are declared in two separate types. What is the difference with operators?

你刚才准确地描述了这种差异.方法重载和操作重载的许多细节都不同.

如果你想采取Foo.Hello()和Bar.Hello(字符串)是Hello的“重载”的位置,这不是一个常见的位置,但它在逻辑上是一致的.

I was under the impression that you cannot change the access modifier when overloading.

你的印象是错的;覆盖虚拟方法时,无法更改访问修饰符.你把它与重载混淆了.

(我注意到有一种情况需要在覆盖虚拟方法时更改访问修饰符;你能推断出它是什么吗?)

I was also under the impression that you can not declare an operator without at least one of the operands being of the type in which you declare the operator.

这几乎是正确的.用户定义的运算符必须具有类型为T的操作数,其中T是封闭的类或结构类型,或者T?如果T是结构类型.

So how can a third class have access to a given operator while another third class can’t unless one belongs to an external assembly and the other doesn`t in which case I do not find it confusing at all and even useful?

你错误地描述了我的例子,这可能更清楚了.这是非法的:

public class Fruit 
{ 
    protected static Shape operator +(Fruit f,Animal a) { ... } 
}

因为这很奇怪:

public class Apple : Fruit
{ 
    ...
    Shape shape = this + giraffe; // Legal!
}
public class Giraffe : Animal
{
    ...
    Shape shape = apple + this; // Illegal!
}

这只是一个例子.一般来说,做一个奇怪的事情是,使运算符的重载决策取决于可访问性域,因此语言设计者确保通过要求用户定义的运算符公开来实现这一点.

I simply find overloading confusing in the context of operators.

很多人都这样做,包括编译器编写者.规范的用户定义的运算符部分非常难以解析,并且Microsoft实现是编译器错误的丰富来源,其中许多是我的错.

I don’t see why simply declaring operators in a type has to described differently from how you would describe declaring any other static method.

嗯,不同的东西是不同的;运算符在很多方面都与方法不同,包括它们的重载决策算法.

我从来没有特别喜欢C#具有可重载的运算符. C#功能是C中相同功能的设计稍好的版本,但在这两种语言中,我认为该功能的成本远远高于相应的用户利益.

谢天谢地,至少C#没有彻底滥用<<操作符惯用C的方式 - 当然它确实滥用和 - 代表.

c# – 对运算符重载感到困惑的更多相关文章

  1. ios – Swift:方法重载只在返回类型上有所不同

    我一直在看Swift类,其中定义了两种方法,它们的返回类型不同.我不习惯使用允许这种语言的语言,所以我去寻找描述它如何在Swift中工作的文档.我在任何地方都找不到任何东西.我本来期望在Swift书中有关于它的整个部分.这记录在哪里?

  2. ios – 在Swift中可以重载=运算符吗?

    可以在Swift中使用overload=运算符来接受例如CGFloat参数吗?我的方法(下面)不起作用.(编辑)重要:上面的编码方法确实有效.请seemyanswerbelow解释为什么我认为没有.解决方法对不起,我很难过.对于CGFloat参数,operator=不需要重载,因为Swift中包含了这样的重载.我试图做类似的事情这失败了,因为我无法放弃让XCode显示的错误让我感到困惑.当然,像我原来的问题(下面)中的方法适用于重载运算符.请随时投票以结束此问题.

  3. iOS上的C#库

    我已经完成了droid开发,答案就是创建一些使用我的C#库的Web服务,然后让droid使用这些服务.我假设同样的方法适用于iOS(正确的???

  4. 二 Swift学习之基本运算符

    二Swift学习之基本运算符————–借鉴老码团队翻译组-Tyrion1.1术语运算符有一元、二元和三元运算符。三元运算符操作三个操作对象,和C语言一样,Swift只有一个三元运算符,就是三目运算符(a?这不同于上面提到的自增和自减运算符。无疑空合运算符(??由于userDefinedColorName是一个可选类型,我们可以使用空合运算符去判断其值。

  5. Swift 运算符重载

    但是现在还有另外一个Swift的特性,你应该知道并且会爱上它,它就是运算符重载。例如:我们在SwiftSpriteKitutilitylibrary代码中使用运算符重载去讲多个CGPoints对象相加,例如下面代码:1234letpt1=CGPointletpt2=CGPointletpt3=pt1+pt2letpt4=pt3*100方便吧?当一个人查看你的代码,他们希望操作符的默认行为,这时候运算符重载会使他们迷惑。幸运的是Swift让你能够定义属于你自己的自定义的运算符。

  6. Swift语法基础:12 - Swift的比较运算, 三目条件运算, 区间运算, 逻辑运算

    在上面的示例中,该运算符用于确定一个名为colorNametoUse的字符串变量的初始值。因为userDefinedColorName是零,表达userDefinedColorName??defaultColorName返回的值的defaultColorName,或”红色”。好了,这次我们就讲到这里,下次我们继续~~

  7. Swift教程10-运算符与C语言的不同

    =,==这些运算符和其他语言的类似,是比较前后两个值是否相等,或者大小关系比较字符串内容是否相等,使用==即可但是Swift新增了===恒等于,是针对于引用类型,如两个对象之间是否是同一个对象与之对应的是!运算符示例Swift新增的??

  8. Swift运算符

    Swift运算符1.赋值运算符“=”用于将一个变量,常量或表达式的值赋值给另一个变量。算术运算符“+”“-”“*”“/”“%”“++”“–”2.溢出运算符1.溢出加“&+”2.溢出减“&-”3.溢出乘“&*”4溢出除“&/”5溢出求余“&%”3.位运算符4.范围运算符本文内容来自《疯狂讲义》

  9. swift中使用xib

    在OC时代,使用xib来管理界面很简单,但是swift下使用xib有点小复杂。由于项目需要,有一个view需要重复使用,storyboard无法满足需求,使用xib更为简便。总结一下swift中使用xib的注意事项:1.新建cocoatouchclass,xib的file‘sowner设置成对应controller2.由于swift不会自动override父类的init方法,所以如果只是按照第一步来做得话,会报错,因此,我们必须手动添加init方法:以上两个方法必须重载,至于默认构造函数最好也重载:

  10. swift笔记-赋值运算符

    复杂些的运算例如逻辑与运算符&&,或让i值加1的便捷自增运算符++i等。Swift支持大部分标准C语言的运算符,且改进许多特性来减少常规编码错误。当然允许你使用Swift的溢出运算符来实现溢出。本章节只描述了Swift中的基本运算符,高级运算符包含了高级运算符,及如何自定义运算符,及如何进行自定义类型的运算符重载。三元运算符操作三个操作对象,和C语言一样,Swift只有一个三元运算符,就是三目运算符(a?

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部