<blockquote>C#中可重载的运算符包括一元、二元及部分特殊运算符,但赋值、逻辑与或、三元等不可重载;常见于自定义数值、几何、时间等类型,提升代码直观性;重载需遵循public static、至少一个参数为当前类型、成对重载==与!=等规则,并保持行为直观、一致,且同步重写Equals与GetHashCode以避免集合操作异常。</blockquote>
<p><img src="https://img.php.cn/upload/article/001/221/864/175582686264554.jpg" alt="c#的operator关键字如何重载运算符?有哪些限制?"></p>
<p>C#中,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">operator</pre>
登录后复制
</div>关键字允许我们为自定义类型定义运算符的行为,让它们也能像内置类型(比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">int</pre>
登录后复制
</div>或<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">string</pre>
登录后复制
</div>)一样,直接使用加减乘除、比较等符号进行操作。说白了,就是给你的类或结构体赋予“算术能力”,这能大大提升代码的可读性和直观性。但这个能力并非没有边界,它有自己的一套规则和限制。</p>
<h3>解决方案</h3>
<p>要重载一个运算符,你需要在你的类或结构体内部,定义一个特殊的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">public static</pre>
登录后复制
</div>方法。这个方法的名字就是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">operator</pre>
登录后复制
</div>关键字后面跟着你想要重载的那个运算符符号。它的参数通常是参与运算的类型,其中至少一个参数必须是你当前定义运算符的类型。</p>
<p>举个例子,假设我们有一个表示二维向量的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Vector2D</pre>
登录后复制
</div>结构体,我们想让两个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Vector2D</pre>
登录后复制
</div>对象可以直接相加:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:csharp;toolbar:false;'>public struct Vector2D
{
public double X { get; }
public double Y { get; }
public Vector2D(double x, double y)
{
X = x;
Y = y;
}
// 重载加法运算符 (+)
public static Vector2D operator +(Vector2D v1, Vector2D v2)
{
// 向量相加就是对应分量相加
return new Vector2D(v1.X + v2.X, v1.Y + v2.Y);
}
// 重载乘法运算符 (*) - 向量乘以标量
public static Vector2D operator *(Vector2D v, double scalar)
{
return new Vector2D(v.X * scalar, v.Y * scalar);
}
// 重载乘法运算符 (*) - 标量乘以向量 (为了对称性)
public static Vector2D operator *(double scalar, Vector2D v)
{
return new Vector2D(v.X * scalar, v.Y * scalar);
}
// 重载相等运算符 (==)
public static bool operator ==(Vector2D v1, Vector2D v2)
{
// 考虑浮点数比较的精度问题,这里简化处理
return v1.X == v2.X && v1.Y == v2.Y;
}
// 重载不相等运算符 (!=)
public static bool operator !=(Vector2D v1, Vector2D v2)
{
return !(v1 == v2); // 直接利用 == 的结果
}
// 重载 == 和 != 后,强烈建议重写 Equals 和 GetHashCode
public override bool Equals(object obj)
{
if (!(obj is Vector2D))
{
return false;
}
return this == (Vector2D)obj;
}
public override int GetHashCode()
{
// 简单的哈希码组合,实际应用中可能需要更复杂的算法
return X.GetHashCode() ^ Y.GetHashCode();
}
public override string ToString()
{
return $"({X}, {Y})";
}
}
// 实际使用
// Vector2D vecA = new Vector2D(1, 2);
// Vector2D vecB = new Vector2D(3, 4);
// Vector2D vecC = vecA + vecB; // 向量相加,结果是 (4, 6)
// Vector2D vecD = vecA * 2.0; // 向量乘以标量,结果是 (2, 4)
// bool areEqual = vecA == new Vector2D(1, 2); // true</pre>
登录后复制
</div><p>可以看到,通过重载,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Vector2D</pre>
登录后复制
</div>实例的操作变得非常自然,就像操作数字一样。</p>
<h3>C#中哪些运算符可以被重载?以及重载的常见应用场景是什么?</h3>
<p>C#允许重载的运算符种类还挺多的,但也不是所有符号都能动。大致可以分为几类:</p>
<ol>
<li>
<p><strong>一元运算符 (Unary Operators)</strong>:</p>
<ul>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div> (一元加,例如 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+a</pre>
登录后复制
</div>)</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">-</pre>
登录后复制
</div> (一元减,例如 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">-a</pre>
登录后复制
</div>)</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">!</pre>
登录后复制
</div> (逻辑非)</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">~</pre>
登录后复制
</div> (按位取反)</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">++</pre>
登录后复制
</div> (自增)</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">--</pre>
登录后复制
</div> (自减)</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">true</pre>
登录后复制
</div> 和 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">false</pre>
登录后复制
</div> (这两个有点特殊,主要用于自定义类型在布尔上下文中的<a style="color:#f60; text-decoration:underline;" title="隐式转换" href="https://www.php.cn/zt/77300.html" target="_blank">隐式转换</a>,比如在<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">if</pre>
登录后复制
</div>语句中直接判断一个自定义对象)</li>
</ul>
</li>
<li>
<p><strong>二元运算符 (Binary Operators)</strong>:</p>
<div class="aritcle_card">
<a class="aritcle_card_img" href="/ai/743">
<img src="https://img.php.cn/upload/ai_manual/000/000/000/175679974577403.png" alt="通义灵码">
</a>
<div class="aritcle_card_info">
<a href="/ai/743">通义灵码</a>
<p>阿里云出品的一款基于通义大模型的智能编码辅助工具,提供代码智能生成、研发智能问答能力</p>
<div class="">
<img src="/static/images/card_xiazai.png" alt="通义灵码">
<span>304</span>
</div>
</div>
<a href="/ai/743" class="aritcle_card_btn">
<span>查看详情</span>
<img src="/static/images/cardxiayige-3.png" alt="通义灵码">
</a>
</div>
<ul>
<li>算术运算符:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">-</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">*</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">/</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">%</pre>
登录后复制
</div></li>
<li>位运算符:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">&</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">|</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">^</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><<</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">>></pre>
登录后复制
</div></li>
<li>相等和关系运算符:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">==</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">!=</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">></pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><=</pre>
登录后复制
</div>, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">>=</pre>
登录后复制
</div></li>
</ul>
</li>
</ol>
<p><strong>常见的应用场景呢?</strong> 我觉得主要集中在以下几个方面:</p>
<ul>
<li>
<strong>自定义数值类型</strong>:比如你写了一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">ComplexNumber</pre>
登录后复制
</div>(复数)类,那自然希望可以直接用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">-</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">*</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">/</pre>
登录后复制
</div>来操作复数对象,而不是写一堆<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">ComplexNumber.Add(c1, c2)</pre>
登录后复制
</div>这样的方法。</li>
<li>
<strong>几何或物理单位</strong>:就像上面<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Vector2D</pre>
登录后复制
</div>的例子,或者你可能有一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Point</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Matrix</pre>
登录后复制
</div>(矩阵)类,重载运算符能让这些类型的数据操作更符合数学直觉。</li>
<li>
<strong>时间与日期处理</strong>:比如一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Duration</pre>
登录后复制
</div>(持续时间)类,你可以重载<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div>让两个持续时间相加,或者<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">DateTime</pre>
登录后复制
</div>对象加上一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Duration</pre>
登录后复制
</div>。</li>
<li>
<strong>特定领域模型</strong>:在某些业务领域,可能存在一些概念,它们之间的“运算”有着明确的语义,比如财务系统中的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Money</pre>
登录后复制
</div>类,你可能希望<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Money A + Money B</pre>
登录后复制
</div>直接得到总金额。</li>
</ul>
<p>在我看来,重载运算符的根本目的就是为了提高代码的“表达力”和“自然度”。当你的代码读起来就像在描述数学公式或现实世界的逻辑时,它的可读性就大大增强了。</p>
<h3>C#重载运算符有哪些重要的限制和规则?</h3>
<p>虽然<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">operator</pre>
登录后复制
</div>关键字很强大,但它不是万能的,有很多限制和必须遵守的规则,否则编译器根本不让你过:</p>
<ol>
<li>
<strong>必须是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">public static</pre>
登录后复制
</div></strong>:这是最基本的要求。运算符重载是针对类型本身的操作,而不是针对某个特定实例的,所以它必须是静态的。同时,为了能在外部被调用,它也必须是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">public</pre>
登录后复制
</div>的。</li>
<li>
<strong>不能重载的运算符</strong>:C#明确禁止重载一些运算符,这通常是因为它们有特殊的语言行为或语义,或者重载它们会带来巨大的混乱。这些包括:<ul>
<li>赋值运算符:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">=</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+=</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">-=</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">*=</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">/=</pre>
登录后复制
</div> 等。这些是语言内置的,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+=</pre>
登录后复制
</div>之类的复合赋值运算符通常会通过调用你重载的二元运算符来实现。</li>
<li>逻辑与/或:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">&&</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">||</pre>
登录后复制
</div>。这两个运算符有短路求值的特性,重载它们会破坏这种行为,导致不可预测的结果。</li>
<li>条件运算符:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">?:</pre>
登录后复制
</div> (三元运算符)。</li>
<li>成员访问:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">.</pre>
登录后复制
</div></li>
<li>类型操作符:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">new</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">typeof</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">sizeof</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">is</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">as</pre>
登录后复制
</div>。</li>
<li>索引器:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">[]</pre>
登录后复制
</div> (虽然它看起来像运算符,但它是通过索引器属性来实现的,而不是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">operator</pre>
登录后复制
</div>关键字)。</li>
<li>checked/unchecked。</li>
</ul>
</li>
<li>
<strong>至少一个参数必须是包含类型</strong>:这是个非常重要的限制。你不能去改变<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">int</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">int</pre>
登录后复制
</div>相加的行为,比如你不能写一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">public static int operator +(int a, int b)</pre>
登录后复制
</div>。重载的运算符至少要有一个参数是你定义运算符的那个类型(或者它的派生类型)。这意味着你只能为你的自定义类型定义新的运算行为。</li>
<li>
<strong>成对出现的运算符</strong>:如果你重载了<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">==</pre>
登录后复制
</div>,那么你<strong>必须</strong>同时重载<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">!=</pre>
登录后复制
</div>。同理,如果你重载了<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><</pre>
登录后复制
</div>,那么你<strong>必须</strong>同时重载<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">></pre>
登录后复制
</div>,并且通常也应该重载<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><=</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">>=</pre>
登录后复制
</div>。这是为了保持逻辑上的一致性,否则你的类型可能会在比较时表现出奇怪的行为。</li>
<li>
<strong>返回类型和参数数量</strong>:<ul>
<li>一元运算符必须只有一个参数。</li>
<li>二元运算符必须有两个参数。</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">==</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">!=</pre>
登录后复制
</div>必须返回<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">bool</pre>
登录后复制
</div>类型。</li>
<li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">true</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">false</pre>
登录后复制
</div>运算符也必须返回<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">bool</pre>
登录后复制
</div>类型。</li>
</ul>
</li>
<li>
<strong>不能重新定义内置运算符的行为</strong>:你无法改变<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">int</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">double</pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">string</pre>
登录后复制
</div>等内置类型已有的运算符行为。你只能为你的自定义类型添加新的行为。</li>
</ol>
<p>这些限制,在我看来,更多的是一种保护机制,防止开发者滥用运算符重载,导致代码变得难以理解和维护。</p>
<h3>重载运算符时需要注意哪些设计原则和最佳实践?</h3>
<p>仅仅知道怎么重载和有哪些限制还不够,更重要的是在什么时候、以什么方式去重载。这里有一些我个人觉得非常重要的设计原则和最佳实践:</p>
<ol>
<li>
<strong>保持直观性,避免“惊喜”</strong>:这是最核心的一点。重载的运算符行为应该与用户对该符号的普遍认知保持一致。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div>就应该像加法,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">*</pre>
登录后复制
</div>就应该像乘法。如果你重载<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div>来做字符串拼接以外的事情,或者<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">*</pre>
登录后复制
</div>来做除法,那绝对是灾难。这种“直观性”是提升<a style="color:#f60; text-decoration:underline;" title="代码可读性" href="https://www.php.cn/zt/55554.html" target="_blank">代码可读性</a>的关键,如果它反而带来困惑,那还不如老老实实写方法。</li>
<li>
<strong>保持一致性</strong>:如果你的类型支持某种运算,那么所有相关的运算都应该被支持。比如,如果你的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Vector2D</pre>
登录后复制
</div>支持<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">+</pre>
登录后复制
</div>,那它也应该支持<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">-</pre>
登录后复制
</div>。</li>
<li>
<strong>考虑不可变性</strong>:对于值类型(<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">struct</pre>
登录后复制
</div>)来说,重载运算符通常应该返回一个新的实例,而不是修改原有的实例。比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Vector2D v3 = v1 + v2;</pre>
登录后复制
</div>,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">v1</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">v2</pre>
登录后复制
</div>不应该被改变,而是生成一个新的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">v3</pre>
登录后复制
</div>。这符合值类型的语义,也避免了意外的副作用。</li>
<li>
<strong>性能考量</strong>:运算符重载本质上就是方法调用。在性能敏感的代码路径中,如果运算符重载会导致大量的对象创建或复杂计算,你需要权衡其带来的可读性提升和潜在的性能开销。</li>
<li>
<strong>与<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Equals</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">GetHashCode</pre>
登录后复制
</div>同步</strong>:这是一个<strong>非常重要且常被忽略的陷阱</strong>。如果你重载了<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">==</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">!=</pre>
登录后复制
</div>运算符,那么你<strong>几乎总是</strong>需要同时重写你的类的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Equals(object obj)</pre>
登录后复制
</div>方法和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">GetHashCode()</pre>
登录后复制
</div>方法。这是因为许多.NET框架组件(比如集合类<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Dictionary<TKey, TValue></pre>
登录后复制
</div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">HashSet<T></pre>
登录后复制
</div>)在比较对象相等性时,默认使用的是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Equals</pre>
登录后复制
</div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">GetHashCode</pre>
登录后复制
</div>,而不是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">==</pre>
登录后复制
</div>运算符。如果不重写,可能会导致你的对象在集合中行为不一致,或者无法正确地被查找、存储。</li>
<li>
<strong>用户定义类型转换</strong>:虽然不是直接的运算符重载,但<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">implicit</pre>
登录后复制
</div>(隐式)和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">explicit</pre>
登录后复制
</div>(显式)关键字定义的用户定义类型转换,在某些场景下可以达到类似运算符的效果,比如将一个自定义类型隐式转换为<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">string</pre>
登录后复制
</div>或<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">int</pre>
登录后复制
</div>。这也可以让代码更流畅,但同样需要谨慎使用,避免隐式转换带来的意外行为。</li>
</ol>
<p>总的来说,运算符重载是一把双刃剑。用得好,代码如诗;用得不好,代码如谜。关键在于理解其背后的机制和限制,并始终以提升代码清晰度和可维护性为目标。</p>
以上就是C#的operator关键字如何重载运算符?有哪些限制?的详细内容,更多请关注php中文网其它相关文章!