2010-04-26 40 views
6

Làm thế nào để viết một phương pháp đơn giản, kiểm tra xem một loại cụ thể là một cấu trúc tùy chỉnh (được tạo ra với public struct { };) hay không.Làm thế nào để xác định xem một loại .NET là một cấu trúc tùy chỉnh?

Kiểm tra Type.IsValueType là không đủ, bởi vì nó cũng đúng với int, long, vv, và thêm một tấm séc để !IsPrimitiveType sẽ không loại trừ decimal, DateTime và có thể một số các loại giá trị khác. Tôi biết rằng hầu hết được xây dựng trong các loại giá trị thực sự "cấu trúc", nhưng tôi chỉ muốn kiểm tra cho "cấu trúc tùy chỉnh"

Những câu hỏi này chủ yếu là giống nhau nhưng mà không có câu trả lời tôi cần:

EDIT: từ các câu trả lời đề cập đến "kiểm tra cho 'hệ thống' tiền tố" là nhất ổn định (mặc dù nó vẫn là một hack). Cuối cùng tôi đã quyết định tạo ra một thuộc tính mà bạn phải trang trí cấu trúc, theo thứ tự khung để chọn nó như là một cấu trúc tùy chỉnh. (Sự lựa chọn khác tôi nghĩ là để tạo ra một giao diện trống rỗng, và để cho các cấu trúc thực hiện mà giao diện trống rỗng, nhưng cách thuộc tính có vẻ tao nhã hơn)

Dưới đây là bản gốc kiểm tra tùy chỉnh struct của tôi nếu ai đó nếu quan tâm:

type.IsValueType && !type.IsPrimitive && !type.Namespace.StartsWith("System") && !type.IsEnum 
+1

Chỉ vì tò mò, tại sao bạn muốn phát hiện điều này? – Joren

+0

Fluent NHibernate + Auto Mapping: đặt tất cả các cấu trúc tùy chỉnh được thực hiện thành các thành phần (đối tượng giá trị); thiết lập bất kỳ loại giá trị nào khác thành một thành phần (như DateTime, hoặc thập phân) sẽ làm hỏng toàn bộ khung công tác (ít nhất là dưới dạng đơn) – SztupY

+0

Thêm vào! type.IsEnum –

Trả lời

5

Vâng, Ngày giờ, số thập phân, v.v. đáp ứng các yêu cầu của bạn. Theo như CLR có liên quan, chúng là các cấu trúc tùy chỉnh. Một hack, nhưng bạn chỉ có thể kiểm tra xem nếu không gian tên bắt đầu với "Hệ thống".

+0

Tất nhiên không gian tên của riêng bạn có thể bắt đầu với Hệ thống ...: Không ai làm được, đúng không? –

+2

Vâng, đó là lý do tại sao tôi gọi đó là hack. –

+0

@MattGreer: tuyệt vời hack bằng cách này, tôi không thể nghĩ rằng :) nhờ –

8

Không có sự khác biệt giữa cấu trúc được xác định trong khung và cấu trúc được xác định bởi chính bạn.

Một vài ý tưởng có thể là:

  • Giữ một danh sách trắng của cấu trúc khung, và loại trừ những;
  • Xác định lắp ráp (DLL) loại được xác định trong và giữ một danh sách trắng của các hội đồng khung.
  • Xác định không gian tên loại cuộc sống và loại trừ các khung công tác khuôn khổ.
+0

Trong bối cảnh của bình luận về sử dụng Fluent NHibernate, một danh sách trắng của "nổi tiếng" cấu trúc sẽ là cách tiếp cận tốt nhất. Danh sách này đủ ngắn để dễ hiểu và có khả năng không bao giờ thay đổi. –

+0

Đồng ý, khi bạn tìm thấy một trong những nguyên nhân gây ra một vụ tai nạn, thêm nó vào danh sách trắng (hoặc danh sách đen hoặc bất cứ điều gì bạn gọi nó), và tiếp tục. Khung không có quá nhiều cấu trúc. – stusmith

+0

Có, nhưng tiếc là không có danh sách cho việc này. Và nếu bạn bỏ lỡ điều gì đó, và sử dụng cấu trúc đó sau đó, bạn sẽ không biết tại sao các khung công tác bắt đầu gặp sự cố – SztupY

2

Bạn có thể kiểm tra xem loại cấu trúc có nằm trong bất kỳ vị trí nào trong phạm vi Không gian tên hệ thống. Nhưng một lần nữa đó không phải là một giải pháp đáng tin cậy.

3

đưa các ý kiến ​​trên vào một phương pháp gia hạn:

public static class ReflectionExtensions { 
     public static bool IsCustomValueType(this Type type) {    
       return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System."); 
     } 
    } 

nên làm việc

-1

Bạn có một giá trị mà đi với kiểu đó? Gọi phương thức ToString và kiểm tra xem chuỗi được trả về có bắt đầu bằng "{" hay không.

Nếu bạn không có giá trị, hãy kiểm tra xem nó có một hàm tạo tham số không. Nếu không, đó là một nhà xây dựng. Nếu có, hãy sử dụng Activator để tạo một cá thể và gọi lại phương thức ToString.

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