我在看一些示例C#代码,并注意到一个示例将返回值包装在()中。
我一直都做:
return myRV;
这样做有什么区别吗?
return (myRV);
Answers:
更新:这个问题是我2010年4月12日博客的主题。感谢您提出有趣的问题!
实际上,没有区别。
从理论上讲可能有所不同。C#规范中有三个有趣的地方,它们可能会有所不同。
首先,将匿名函数转换为委托类型和表达式树。考虑以下:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1
显然是合法的。是F2
吗 从技术上讲,没有。规范在6.5节中说,存在从lambda表达式到兼容委托类型的转换。那是lambda表达式吗?不。这是一个带括号的表达式,其中包含lambda表达式。
Visual C#编译器在这里犯了一个小的规范冲突,并为您丢弃了括号。
第二:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3
是合法的。是F4
吗 否。第7.5.3节指出,带括号的表达式不能包含方法组。同样,为了您的方便,我们违反了规范并允许进行转换。
第三:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5
是合法的。是F6
吗 否。规范指出,存在从文字零到任何枚举类型的转换。“ (0)
”不是文字零,它是一个括号,后跟文字零,后跟一个括号。我们在这里违反了规范,实际上允许任何等于零的编译时常数表达式,而不仅仅是文字零。
因此,在每种情况下,即使从技术上讲,这样做都是违法的,我们仍允许您摆脱它。
在某些特殊情况下,括号的存在会影响程序的行为:
1。
using System;
class A
{
static void Foo(string x, Action<Action> y) { Console.WriteLine(1); }
static void Foo(object x, Func<Func<int>, int> y) { Console.WriteLine(2); }
static void Main()
{
Foo(null, x => x()); // Prints 1
Foo(null, x => (x())); // Prints 2
}
}
2。
using System;
class A
{
public A Select(Func<A, A> f)
{
Console.WriteLine(1);
return new A();
}
public A Where(Func<A, bool> f)
{
return new A();
}
static void Main()
{
object x;
x = from y in new A() where true select (y); // Prints 1
x = from y in new A() where true select y; // Prints nothing
}
}
3。
using System;
class Program
{
static void Main()
{
Bar(x => (x).Foo(), ""); // Prints 1
Bar(x => ((x).Foo)(), ""); // Prints 2
}
static void Bar(Action<C<int>> x, string y) { Console.WriteLine(1); }
static void Bar(Action<C<Action>> x, object y) { Console.WriteLine(2); }
}
static class B
{
public static void Foo(this object x) { }
}
class C<T>
{
public T Foo;
}
希望您在实践中永远不会看到这一点。