返回myVar与return(myVar)之间有区别吗?

chr*_*ris 87 c# syntax

我正在查看一些示例C#代码,并注意到一个示例将返回包含在()中.

我一直都这么做:

return myRV;
Run Code Online (Sandbox Code Playgroud)

这样做是否有区别:

return (myRV);
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 229

更新:这个问题是我的博客2010年4月12日的主题.谢谢你这个有趣的问题!

在实践中,没有区别.

在理论上有可能是一个区别.C#规范中有三个有趣的点,这可能会产生差异.

首先,将匿名函数转换为委托类型和表达式树.考虑以下:

Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
Run Code Online (Sandbox Code Playgroud)

F1显然是合法的.是F2吗?从技术上讲,没有.该规范在6.5节中说明存在从lambda表达式到兼容委托类型的转换.那是一个lambda表达式吗?不.它是带括号的表达式,包含lambda表达式.

Visual C#编译器在此处进行小规格违规并丢弃括号.

第二:

int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
Run Code Online (Sandbox Code Playgroud)

F3是合法的.是F4吗?No. 7.5.3节规定括号表达式可能不包含方法组.同样,为方便起见,我们违反了规范并允许转换.

第三:

enum E { None }
E F5() { return 0; }
E F6() { return (0); }
Run Code Online (Sandbox Code Playgroud)

F5是合法的.是F6吗?不.规范声明存在从字面零到任何枚举类型的转换." (0)"不是字面零,它是一个括号后跟字面零,后跟括号.我们违反了这里的规范,实际上允许任何编译时常量表达式等于零,而不仅仅是字面零.

因此,在每种情况下,我们都允许您逃脱它,即使技术上这样做是非法的.

  • @Anthony:当我这样做时,我只是告诉别人我的学位是*数学*,而不是算术*. (32认同)
  • @Bruno:所需要的只是大约八或一万小时的特定科目的学习时间,你也可以成为专家.这在四年的全职工作中很容易实现. (18认同)
  • @Jason:我认为前两种情况下的规范违规只是从未被发现的错误.历史上,初始绑定传递一直非常积极地过早地优化表达式,其结果之一是括号被很早地丢弃,早于它们应该被抛弃.几乎在所有情况下,所有这一切都使得直观明显的程序按照应有的方式工作,所以我并不十分担心.第三个案例分析如下:http://blogs.msdn.com/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspx (12认同)
  • 从理论上讲,实践和理论是相同的,但在实践中他们从来都不是. (7认同)
  • 从理论上讲,在实践中,*是*差异(我不确定Mono是否允许这3个案例,并且不知道任何其他C#编译器,因此在实践中可能存在或可能没有差异) .违反C#规范意味着您的代码将无法完全移植.与Visual C#不同,某些C#编译器可能不会违反这些特定情况下的规范. (6认同)
  • 所以修改规范; 区分`表达式'和`(表达式)`(或`((((表达式))))`)是不好的语言设计. (6认同)
  • 该死的,当我读到Lippert的见解时,我几乎感到羞耻......我不认为我对任何主题有所了解,甚至接近他对C#的了解程度. (5认同)
  • @Anthony:每天8小时x每周5天x每年50周=每年2000小时.每年8000小时/ 2000小时= 4年.你在那里每周工作80小时? (5认同)
  • @Eric:在那里,我读到了8或10万*年*的学习!:) (4认同)
  • @Eric,那些是~80小时的周!去度假. (3认同)
  • @Eric,我从纯粹的失败中获得了这个数字,就在那里.:(我通常擅长心理数学,但不是今天.我责备变老. (3认同)
  • @Eric Lippert:为何违规?我看到你说方便了,但你如何权衡违反规范与方便的平衡?它是一个为方便起见的功能吗?:-) (2认同)
  • @John:(1)因为你需要能够将一组标志初始化为某种东西; 最佳实践是标志枚举的提供者提供等于零但不是每个人都做的"无".(2)因为将枚举字段自动初始化为零似乎很奇怪,但无法检查它是否仍然是没有强制转换的值.由于各种问题,我们实际上允许任何常量零,而不仅仅是任何文字零,转换为枚举. (2认同)

Vla*_*kov 40

当括号的存在可能对程序行为产生影响时,存在极端情况:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

希望你在实践中永远不会看到这一点.

  • 您应该详细说明为什么会发生这种现象。 (2认同)

Jar*_*Par 26

不,除了语法之外没有区别.