提问人:michuu 提问时间:4/6/2023 最后编辑:michuu 更新时间:4/7/2023 访问量:146
使用一元加运算符安全吗?
Is it safe to use the unary plus operator?
问:
我看到的代码是这样的:
double d = GetDouble();
DoSomething(+d);
DoSomething(-d);
我知道其中有潜在的危险,不建议在 C++ 中使用一元只是为了强调值是正的。“只是为了强调价值是积极的”是一种心理捷径。我知道它不会使负值为正值。+
<EDIT>
</EDIT>
C# 语言参考对此没有太多说明:
一元 + 运算符返回其操作数的值。
SO上有一个关于这个问题的问题,但它被标记为C,C++和C#,并且没有一个答案明确提到C#。
答:
1赞
Peter Csala
4/6/2023
#1
+
并且不会更改原始的双精度值,如果这就是您所说的安全。-
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
评论
0赞
michuu
4/6/2023
它是否以任何方式更改了值类型,或者它始终是无操作的?
0赞
Peter Csala
4/6/2023
@michuu否,它不会更改值类型。即使您更改 to 或第一部分也很好用。将导致编译时错误。double
uint
byte
d = -7
2赞
Magnetron
4/6/2023
@PeterCsala正如 Sweeper 的回答所指出的,如果变量是 a 或一元将更改为short
byte
int
0赞
Peter Csala
4/6/2023
@Magnetron是的,我看到了。
7赞
Sweeper
4/6/2023
#2
正如您链接的问题的答案所说,C(++) 中的一元确实做了一些事情,并且不一定是无操作。这在 C# 中也是如此。+
C# 只有这些一元运算符(参见规范):+
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");
}
}
C.Foo(x)
其中 a 将打印 ,但将打印 。x
short
short
C.Foo(+x)
int
像上述这样的情况是否经常发生,以至于造成“坏”或“不安全”的做法?这是由你来决定的。+x
当然,如果是自定义结构/类类型,那么基本上可以做任何事情。一元是可重载的。x
+x
+
评论
0赞
michuu
4/6/2023
这种类型更改行为是否使 C# 社区中不推荐使用?
1赞
Sweeper
4/6/2023
@michuu 不,据我所知。像 这样的情况并不多,其中存在过载和执行完全不同操作的过载。毕竟,重载应该做类似的事情。因此,即使你调用了“错误”的,它的行为仍然应该相同(只是额外无用的转换)。当类型真正重要时,最好为方法提供不同的名称。C.Foo
int
short
0赞
michuu
4/6/2023
好的,谢谢你的准确回答!
0赞
Narish
4/6/2023
#3
其他答案很好地解释了使用 .+
只是想标记一下,就像在 C/C++ 中一样,还有整数类型,所有类型都有无符号版本。当然,两者都有相同的担忧,即在对他们进行糟糕的操作时进行包装
下面的代码片段只是一个笑话,不要杀我,但这里有一个扩展方法,可以检查数值类型是否为正数,而不会有更改原始值或键入的风险
public static class NumericExtensions<T> where T : struct
{
public static bool IsPositive(this T num) =>
num switch
{
num is uint _ => true,
num is int i => i > 0,
num is ulong _ => true,
num is long l => l > 0,
num is double d => d > 0,
num is float f => f > 0,
num is decimal m => m > 0m
//... add remaining numeric types
_ => false //or throw exception
};
}
评论
+