Unary plus operator 安全使用吗?

huangapple go评论68阅读模式
英文:

Is it safe to use the unary plus operator?

问题

我看到的代码如下:
```cs
double d = GetDouble();
DoSomething(+d);
DoSomething(-d);

我知道在C++中使用一元+只是为了强调该值为正是潜在的危险做法,也不被推荐。""仅仅是为了强调该值为正""是一种心理快捷方式。我知道它不能将负值变为正值。

C#语言参考对此并没有多少说明:

一元+运算符返回其操作数的值。

在SO上有一个问题讨论了这个问题,但标记为C、C++和C#,没有一个答案明确提及了C#。


<details>
<summary>英文:</summary>

I saw code that goes like this:
```cs
double d = GetDouble();
DoSomething(+d);
DoSomething(-d);

I know in it is potentially dangerous and not recommended in C++ to use the unary + just to emphasize that the value is positive. &lt;EDIT&gt;"just to emphasize that the value is positive" was a mental shortcut. I know it doesn't make a negative value positive.&lt;/EDIT&gt;

The C# language reference doesn't say much about it:
> The unary + operator returns the value of its operand.

There is a question on SO about this, but it is tagged with C, C++ and C#, and none of the answers clearly mentions C#.

答案1

得分: 7

正如你所链接的问题的[这个答案][1]所说,在C(++)中的一元 `+` 确实会*执行某些操作*,并不一定是空操作。在C#中也是如此。

C# 只有这些一元 `+` 操作符(参见[规范][2]):

```csharp
int operator +(int x);
uint operator +(uint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);

因此,如果 x 是一个 short+x 将是 int 类型,因为通过重载决议选择了第一个操作符。因此,类似以下的代码将无法编译:

short x = 1;
short y = +x;

这也会影响到重载决议等其他事情。就像在这个答案中呈现的代码一样,如果你这样做:

public class C {
    public static void Foo(int x) {
        Console.WriteLine("int");
    }
    
    public static void Foo(short x) {
        Console.WriteLine("short");
    }
}

对于 x 是一个 short 的情况,C.Foo(x) 会打印 short,但 C.Foo(+x) 将打印 int

类似上述情况发生的频率是否足够高,使得 +x 成为一个“不好”的或“不安全”的实践?这取决于你的判断。

当然,如果 x 是一个自定义结构体/类类型,那么 +x 可以做任何事情。一元 + 是可以重载的。


<details>
<summary>英文:</summary>

As [this answer][1] of the question you linked says, unary `+` in C(++) does *do something*, and is not necessarily a no-op. This is true in C# too.

C# only has these unary `+` operators (See [spec][2]):

int operator +(int x);
uint operator +(uint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);


So if `x` is a `short`, `+x` would be of type `int`, because the first operator is selected by overload resolution. As a result, something like this does not compile:

short x = 1;
short y = +x;


This also affects overload resolution, among other things. Just like the code presented in [this answer][1], if you do:

public class C {
public static void Foo(int x) {
Console.WriteLine("int");
}

public static void Foo(short x) {
    Console.WriteLine(&quot;short&quot;);
}

}


`C.Foo(x)` where `x` is a `short` will print `short`, but `C.Foo(+x)` will print `int`.

Does this situations like the above happens often enough that makes `+x` a &quot;bad&quot; or &quot;unsafe&quot; practice? That is for you to decide.

Of course, if `x` is of a custom struct/class type, then `+x` could do basically anything. Unary `+` is overloadable.





  [1]: https://stackoverflow.com/a/3903114/5133585
  [2]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1182-unary-plus-operator

</details>



# 答案2
**得分**: 1

+- 如果你指的是安全的话,它们不会改变原始的双精度值。

double d = 7d;
Console.WriteLine(d);  //7
Console.WriteLine(+d); //7
Console.WriteLine(-d); //-7
Console.WriteLine(d);  //7

//或者
d = -7d;
Console.WriteLine(d);  //-7
Console.WriteLine(+d); //-7
Console.WriteLine(-d); //7
Console.WriteLine(d);  //-7
英文:

+ and - will not change the original double value if that's what you mean by safe.

double d = 7d;
Console.WriteLine(d);  //7
Console.WriteLine(+d); //7
Console.WriteLine(-d); //-7
Console.WriteLine(d);  //7

//OR
d = -7d;
Console.WriteLine(d);  //-7
Console.WriteLine(+d); //-7
Console.WriteLine(-d); //7
Console.WriteLine(d);  //-7

答案3

得分: 0

以下是翻译好的内容:

其他答案已经提供了关于使用 `+` 的详细解释。

只是想提醒一下,就像在 C/C++ 中一样,所有整数类型都有无符号版本。当对它们进行不当操作时,它们都会存在相同的[问题](https://www.learncpp.com/cpp-tutorial/unsigned-integers-and-why-to-avoid-them/),会发生环绕。

以下代码片段只是一个玩笑,请不要生气,但这里有一个扩展方法,用于检查数值类型是否为正数,而不会改变原始值或类型。

```csharp
public static class NumericExtensions&lt;T&gt; where T : struct
{
    public static bool IsPositive(this T num) =&gt;
        num switch  
        {  
            num is uint _ =&gt; true,
            num is int i =&gt; i &gt; 0,
            num is ulong _ =&gt; true,
            num is long l =&gt; l &gt; 0,
            num is double d =&gt; d &gt; 0,
            num is float f =&gt; f &gt; 0,
            num is decimal m =&gt; m &gt; 0m
            //... 添加其余的数值类型
            _ =&gt; false //或抛出异常
        };
}
英文:

The other answers have provided a great explanation of what will go on with use of +.

Just wanted to flag that just like in C/C++ there also is the integral numeric types all have unsigned versions. Of course, both share the same concerns of wrapping around when bad operations are done with them

The following code snippet is just a joke, don't kill me, but here is an extension method to check if a numeric type is positive without risk of altering the original's value or typing

public static class NumericExtensions&lt;T&gt; where T : struct
{
    public static bool IsPositive(this T num) =&gt;
        num switch  
        {  
            num is uint _ =&gt; true,
            num is int i =&gt; i &gt; 0,
            num is ulong _ =&gt; true,
            num is long l =&gt; l &gt; 0,
            num is double d =&gt; d &gt; 0,
            num is float f =&gt; f &gt; 0,
            num is decimal m =&gt; m &gt; 0m
            //... add remaining numeric types
            _ =&gt; false //or throw exception
        };
}

huangapple
  • 本文由 发表于 2023年4月6日 20:27:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949509.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定