2011-06-17 9 views
13

Tôi đang viết thuộc tính bảo mật tuỳ chỉnh và có hành vi biên dịch lạ ... Khi tôi đang sử dụng thuộc tính tại cùng một tập tin, các giá trị tham số mặc định hoạt động tốt:Đây có phải là một thông số tùy chọn trình biên dịch C# 4.0 không?

using System.Security.Permissions; 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute { 
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
    public override System.Security.IPermission CreatePermission() { return null; } 
} 

[Foo] class Program { 
    static void Main(string[] args) { } 
} 

Nhưng khi tôi đang tách mã trên vào hai tập tin như vậy - tập 1:

using System.Security.Permissions; 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute { 
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
    public override System.Security.IPermission CreatePermission() { return null; } 
} 

Và nộp 2:

[Foo] class Program { 
    static void Main(string[] args) { } 
} 

tôi đã có một lỗi biên dịch:

Error: 'FooAttribute' does not contain a constructor that takes 0 arguments

này chỉ xảy ra với CodeAccessSecurityAttribute thừa kế, trông rất lạ ...

+2

Mối quan hệ giữa FooAttribute, trong nguồn và DebugCallTraceAttribute, trong thông báo lỗi là gì? –

+2

Có lý do nào cho 'SecurityAttribute' trong đoạn đầu tiên và' CodeAccessSecurityAttribute' trong phần thứ hai? Có vẻ như đây là như nhau cho một trường hợp thử nghiệm tối thiểu hợp lệ. (Ví dụ: nó có liên quan đến sự thay đổi này hoặc đang ở trong hai tệp hay cả hai?) –

+0

xin lỗi, lúc 3 giờ sáng tại Moscow, tất cả các lỗi đoạn mã đều được sửa lỗi – ControlFlow

Trả lời

13

Vì vậy, tôi không có một câu trả lời chính xác nhưng tôi lấy nó như xa như tôi có thể nhìn vào nó. Tôi nghĩ rằng tôi hiểu tại sao nó xảy ra khi bạn kế thừa từ CodeAccessSecurityAttribute và không SecurityAttribute. Nếu bạn nhìn vào IL tạo ra khi áp dụng các thuộc tính Foo khi nó được thừa hưởng từ CodeAccessSecurityAttribute nó trông như thế này:

.permissionset demand = {class 'ConsoleApplication1.FooAttribute, ConsoleApplication1, Version=1.0.0.0, Culture=neutral' = {}} 

Khi Foo thừa hưởng từ SecurityAttribute nó trông giống như sau:

.custom instance void ConsoleApplication1.FooAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = (01 00 02 00 00 00 00 00) 

Rõ ràng CodeAccessSecurityAttribute thay đổi đáng kể IL được tạo ra bằng cách áp dụng thuộc tính.

Nhìn vào IL hơn nếu chúng ta thay đổi khai Foo được như như sau

[Foo(SecurityAction.Demand)] 

Chúng tôi nhận được IL sau:

.permissionset demand = {class 'ConsoleApplication1.FooAttribute, ConsoleApplication1, Version=1.0.0.0, Culture=neutral' = {}} 

của nó giống như nó là khi chúng tôi đã không chỉ định tham số tùy chọn. Hơn nữa chúng ta có thể gây ra lỗi không chỉ thông qua việc tách các thuộc tính và các lớp Program vào các tập tin riêng biệt chúng ta có thể gây ra nó bằng cách sắp xếp lại các tập tin trong lớp học như thế này:

[Foo] 
class Program 
{ 

    static void Main(string[] args) {} 


} 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute 
{ 
    public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
    public override System.Security.IPermission CreatePermission() { return null; } 
} 

Thậm chí thú vị hơn nếu chúng ta thực hiện như sau với lớp OtherOther2 đưa ra lỗi nhưng Program thì không. Chỉ có các lớp học mà đi trước Foo trong file sẽ có lỗi

[Foo] 
class Other 
{ 

} 

[Foo] 
class Other2 
{ 
} 

[System.Serializable] 
sealed class FooAttribute : CodeAccessSecurityAttribute 
{ 
     public FooAttribute(SecurityAction action = SecurityAction.Demand) : base(action) { } 
     public override System.Security.IPermission CreatePermission() { return null; }  } 

[Foo] 
class Program 
{ 

    static void Main(string[] args) {} 
} 

Điều này có nói với tôi là có một vấn đề nào đó trong quá trình xây dựng. Tôi không biết đủ về cách Code Access Security hoạt động để đặt ngón tay của tôi vào vấn đề chính xác là gì. Phải có một phần của quá trình xem xét các CodeAccessSecurityAttributes và thực hiện điều gì đó với việc cố gắng áp dụng SecurityAction cho mã. Tôi giả sử nó xây dựng một số loại siêu dữ liệu cho hội đồng. Nó phải thực hiện điều này theo một cách nào đó để nó không nhìn thấy tham số tùy chọn cho đến khi nó đã vượt qua lớp Program. Sau đó, nó phải sử dụng siêu dữ liệu đó theo một cách nào đó trong quá trình xây dựng và đó là nơi bạn đang gặp sự cố. Để biết thêm chi tiết, chúng tôi sẽ phải hy vọng ai đó biết được trình biên dịch, tức là Eric có thể làm sáng tỏ nó. Tôi muốn gửi nó trên connect.microsoft.com như một trong những ý kiến ​​được đề xuất vì nó có vẻ giống như một lỗi gây ra bởi các thứ tự được duyệt qua.

+1

+1 từ tôi để phân tích tốt. – Jehof

+0

Nếu chỉ ** tất cả ** báo cáo lỗi được nghiên cứu và viết rất tốt! –