2010-11-18 43 views
6

Trong C#, tôi có một số mã API "an toàn" liên quan đến độ cao UAC. Nó liên quan đến việc kích thước của một enum (như sau)C# sizeof (enum) thay thế? (để workaround resharper sai lỗi)?

int myEnumSize = sizeof (MyEnum); 

Mã chính nó là hợp lệ, biên dịch, hoạt động chính xác vv Nhưng Resharper sai cờ nó như là một lỗi ("Không thể sử dụng cấu trúc không an toàn trong bối cảnh an toàn") trong giải pháp. (Starting with version 2.0 of C#, applying sizeof to built-in types no longer requires that unsafe mode be used.) Tôi yêu Resharper, và tôi thích phân tích giải pháp, nhưng với mã này trong giải pháp tôi có một chấm đỏ lớn ở góc khiến tôi luôn nghĩ rằng có thứ gì đó bị hỏng. Nếu tôi yêu cầu resharper bỏ qua lỗi này, nó sẽ trở lại trong vòng vài phút.

Tôi sẽ nêu vấn đề với JetBrains, nhưng tôi đã xem bộ theo dõi của họ và họ đã có một bản ghi đã bị bỏ qua kể từ tháng 3. Nhìn xa hơn, họ có ít nhất hai trường hợp khác đã đăng nhập trở lại trong vài năm, cả hai đều bị loại bỏ với trạng thái "không repro". Tôi không muốn đăng ký theo dõi của họ chỉ để bỏ phiếu này. Tôi vẫn có thể ngừng thở trong nhiều năm. Cách nhanh nhất để chuyển tiếp chỉ là giải quyết vấn đề.

Phương án thay thế tốt nhất vẫn chính xác và có ít cơ hội nhất gây ra một người bảo trì bất kỳ sự cố nào sau này?

tôi có thể mã hóa cứng nó để:

int myEnumSize = 4; 

Có là giải pháp chính xác hơn? - Mà không sử dụng sizeof (enum)?

Btw:

Marshal.SizeOf() 

là hoàn toàn "an toàn" nhưng trả về kích thước sai.

PS. Mã trong câu hỏi bị ảnh hưởng nặng nề bởi mã demo UACSelfElvation từ Microsoft. Nếu bạn muốn biết thêm chi tiết. Nhưng tôi không nghĩ chúng có liên quan.

Trả lời

6

Trông xấu xí, nhưng có thể làm việc:

int myEnumSize = Marshal.SizeOf(Enum.GetUnderlyingType(typeof(MyEnum))); 


Sửa bởi John Gietzen:
Proof:

enum Enum1 : sbyte { A, B, C, D } 
enum Enum2 : short { A, B, C, D } 
enum Enum3 : int { A, B, C, D } 
enum Enum4 : long { A, B, C, D } 

enum Enum5 : byte { A, B, C, D } 
enum Enum6 : ushort { A, B, C, D } 
enum Enum7 : uint { A, B, C, D } 
enum Enum8 : ulong { A, B, C, D } 

sizeof (Enum1): 1
sizeof (Enum2): 2
sizeof (Enum3): 4
sizeof (Enum4): 8
sizeof (Enum5): 1
sizeof (Enum6): 2
sizeof (Enum7): 4
sizeof (Enum8): 8

Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum1))): 1
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum2))): 2
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum3))): 4
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum4))): 8
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum5))): 1
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum6))): 2
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum7))): 4
Marshal.SizeOf (Enum.GetUnderlyingType (typeof (Enum8))): 8

+1

Xác nhận công việc. –

+1

Hoàn hảo. Điều này thật đúng với gì mà tôi đã tìm kiếm. Nó hoạt động, và mặc dù nó không phải là đẹp, với một bình luận cho thấy cách ngắn gọn hơn và chỉ ra lý do tại sao nó không được sử dụng ở đây, nó sẽ là tuyệt vời. Cảm ơn bạn. Đây là chính xác những gì tôi đã hy vọng khi yêu cầu Stackoverflow. – DanO

1

Giải pháp đúng là thêm nhận xét trước dòng này cho biết cảnh báo do công cụ tạo ra không chính xác. Điều này sẽ ngăn cản các nhà bảo trì trong tương lai trở nên bối rối và cố gắng sửa chữa một thứ gì đó không bị hỏng.

+0

Làm cách nào để khắc phục sự cố của anh ấy? –

+0

Ngắn của việc sửa lỗi trong Resharper, có thực sự không phải là một giải pháp, là có? – cdhowie

+0

Không, không khắc phục. Nhưng một cách giải quyết? có lẽ. Đó là những gì anh ta hỏi. –

0

Tôi tưởng tượng (nếu bạn thực sự thực sự muốn), bạn có thể sử dụng chuyển đổi/trường hợp trên điều tra. Nhưng tôi đoán là sizeof là có lý do.

0

Nếu bạn quan tâm đến việc nhận được kích thước của đối tượng dữ liệu cơ bản của enum, có lẽ cách tốt hơn là giữ đối tượng System.Type đầu tiên.

Type type = typeof (MyEnum); 
int enumSize = sizeof (Enum.GetUnderlyingType (type)); 
0

bạn có thể bỏ qua nó trong ReSharper nhưng đó là một chút đau đớn và thỏa hiệp/thay đổi thiết kế của bạn. Bạn có thể đặt định nghĩa Enum và phương thức để lấy kích thước (sử dụng sizeof) trong một lớp trong tệp riêng của nó và nhấp vào ReSharper> Tùy chọn ...> Kiểm tra mã> Cài đặt> Chỉnh sửa mục để bỏ qua và sau đó chọn tệp đó (I đang sử dụng R # 5.1).

Rõ ràng bạn sẽ không nhận được phân tích mã nhưng bạn vẫn nhận được định dạng mã làm sạch.

Các vấn đề liên quan