Tôi đang xem một số mã C # ví dụ và nhận thấy rằng một ví dụ đã bao gồm return trong ().
Tôi luôn luôn làm:
return myRV;
Có sự khác biệt khi làm:
return (myRV);
Câu trả lời:
CẬP NHẬT: Câu hỏi này là chủ đề trên blog của tôi vào ngày 12 tháng 4 năm 2010 . Cảm ơn vì câu hỏi thú vị!
Trong thực tế, không có sự khác biệt.
Về lý thuyết có thể có một sự khác biệt. Có ba điểm thú vị trong đặc tả C # nơi điều này có thể tạo ra sự khác biệt.
Đầu tiên, chuyển đổi các hàm ẩn danh thành các kiểu ủy quyền và cây biểu thức. Hãy xem xét những điều sau:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1
rõ ràng là hợp pháp. Là F2
? Về mặt kỹ thuật, không. Thông số kỹ thuật cho biết trong phần 6.5 rằng có sự chuyển đổi từ biểu thức lambda sang kiểu đại biểu tương thích. Đó có phải là một biểu thức lambda không? Không. Đó là một biểu thức được đặt trong ngoặc đơn chứa biểu thức lambda .
Trình biên dịch Visual C # thực hiện một vi phạm thông số kỹ thuật nhỏ ở đây và loại bỏ dấu ngoặc đơn cho bạn.
Thứ hai:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3
là hợp pháp. Là F4
? Không. Phần 7.5.3 nói rằng một biểu thức trong ngoặc đơn có thể không chứa một nhóm phương thức. Một lần nữa, để thuận tiện cho bạn, chúng tôi vi phạm đặc điểm kỹ thuật và cho phép chuyển đổi.
Ngày thứ ba:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5
là hợp pháp. Là F6
? Không. Thông số kỹ thuật nói rằng có sự chuyển đổi từ số 0 theo nghĩa đen sang bất kỳ kiểu liệt kê nào. " (0)
" không phải là số 0 theo nghĩa đen, nó là dấu ngoặc đơn theo sau là số 0 theo nghĩa đen, theo sau là dấu ngoặc đơn. Chúng tôi vi phạm đặc điểm kỹ thuật ở đây và thực sự cho phép bất kỳ biểu thức hằng số thời gian biên dịch nào bằng 0 chứ không chỉ bằng 0 theo nghĩa đen.
Vì vậy, trong mọi trường hợp, chúng tôi cho phép bạn thoát khỏi nó, mặc dù về mặt kỹ thuật, làm như vậy là bất hợp pháp.
Có những trường hợp góc khi sự hiện diện của dấu ngoặc đơn có thể ảnh hưởng đến hoạt động của chương trình:
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;
}
Hy vọng bạn sẽ không bao giờ thấy điều này trong thực tế.
Một cách tốt để trả lời những câu hỏi như thế này là sử dụng Reflector và xem IL được tạo ra. Bạn có thể học rất nhiều về tối ưu hóa trình biên dịch và những thứ như vậy bằng cách dịch ngược các hợp ngữ.