2013-02-14 21 views
8

Tôi có lớp nàyC#: Làm thế nào để biết một đối tượng có thuộc lớp tùy chỉnh hoặc kiểu native/.NET không?

public class MyViewModel { 
    public MyClass Thing { get; set; } 
    public int Id { get { return Thing.Id; } } 
    public string Name { get { return Thing.Name; } } 
} 

tôi nhận thấy khi tôi gắn nó vào một ASP.NET GridView, nó tự động bỏ qua Thing, và cho một lý do chính đáng (ví dụ. Vì nếu không nó sẽ duy hiển thị "MyNameSpace vô nghĩa. MyClass "ở tất cả các hàng)

Tôi đang cố gắng thực hiện một điều tương tự trong phương pháp này.

public static string ConvertToCsv<T>(IEnumerable<T> items) 
{ 
    foreach (T item in items) 
    { 
    if(item is not a native/.NET class) // <-- How do you do this? 
     continue; 
    else // If it is a string/int/bool/DateTime or something meaningful 
    { 
     ... 
    } 
    } 
} 
+0

thể trùng lặp của [Làm thế nào để xác định xem một DLL là một lắp ráp hoặc mẹ đẻ được quản lý (ngăn chặn tải một dll bản địa)?] (Http://stackoverflow.com/questions/367761/how-to-determine -whether-a-dll-is-a-managed-assembly-hoặc-native-prevent-loading) - kiểm tra câu trả lời cho điểm cao nhất –

+0

Cảm ơn Jeremy nhưng tôi không nói về các tệp hoặc DLL – Aximili

Trả lời

11

Không chắc về hiệu suất, nhưng bạn có thể sử dụng somthing dọc theo dòng của

if(item.GetType().Namespace.StartsWith("System")) 
{ 
    // do stuff 
} 

Hoặc bộ lọc trước khi vòng lặp

public static string ConvertToCsv<T>(IEnumerable<T> items) 
{ 
    foreach (T item in items.Where(i => i.GetType().Namespace.StartsWith("System"))) 
    { 

    } 
} 

Edit: sau khi một thử nghiệm nhanh các phương pháp trên có một số sai sót, Nếu đối tượng của bạn là nullable (MyViewModel?) nó sẽ được chọn trong kiểm tra này (System.Nullable<MyViewModel>).

Vì vậy, có lẽ bạn có thể sử dụng:

public static string ConvertToCsv<T>(IEnumerable<T> items) 
{ 
    foreach (T item in items.Where(i => i.GetType().Module.ScopeName.Equals("CommonLanguageRuntimeLibrary"))) 
    { 

    } 
} 

chỉnh sửa khác: Dường như có một số vấn đề với phương pháp cuối cùng cũng có, Nhưng, lần này dưới đây là của xa nhanh nhất và đáng tin cậy nhất, Chúng tôi chỉ tạo danh sách System.Objects từ Assembly, và kiểm tra xem đối tượng item của bạn có nằm trong danh sách đó không.

private List<Type> _systemTypes; 
public List<Type> SystemTypes 
{ 
    get 
    { 
     if (_systemTypes == null) 
     { 
      _systemTypes = Assembly.GetExecutingAssembly().GetType().Module.Assembly.GetExportedTypes().ToList(); 
     } 
     return _systemTypes; 
    } 
} 

public static string ConvertToCsv<T>(IEnumerable<T> items) 
{ 
    foreach (T item in items.Where(i => SystemTypes.Contains(i.GetType()))) 
    { 
     // is system type 
    } 
} 
+1

Thứ hai của bạn là imo thanh lịch hơn –

+0

Tại sao không chỉ lưu trữ các không gian tên? Nó có thể nhanh hơn nữa. Mẫu tuyệt vời mặc dù. – Edgar

+0

'typeof (Assembly)' thay vì 'Assembly.GetExecutingAssembly(). GetType(). Module' có vẻ thanh lịch hơn và làm tương tự. Dòng đầy đủ sẽ là '_systemTypes = typeof (Assembly) .Assembly.GetExportedTypes(). ToList();' Hơn thế nữa rõ ràng hơn Type được sử dụng để nhắm mục tiêu ở đây. Có thể dễ dàng sử dụng để nhìn trộm tại các hội đồng khác ngoài mscorlib. –

0

Bạn sẽ phải nhìn nó trong một bảng băm được xác định trước hoặc từ điển ... nói bằng cách liệt kê tất cả các hội đồng là một phần của .NET Framework SDK và lưu trữ tên đầy đủ trong từ điển.

0

Tôi biết điều này là cũ nhưng tôi nghĩ rằng bạn đang tìm kiếm phương pháp.

Type type = result.GetType(); 
PropertyInfo[] properties = type.GetProperties(); 
foreach (PropertyInfo property in properties) 
{ 
    string prs = property.GetMethod.ToString(); 
    if(!prs.StartsWith("System")) 
    { 
     //IS CLass 
    } else { 
     Console.WriteLine(property.Name + ":::" + property.Value); 
    } 
} 
Các vấn đề liên quan