2010-05-27 38 views
6

Tôi có một số đối tượng được tạo khuôn mẫu mà tất cả đều triển khai cùng một giao diện:C# xác định loại chung

I.E.

MyObject<datatype1> obj1; 
MyObject<datatype2> obj2; 
MyObject<datatype3> obj3; 

Tôi muốn để lưu trữ các đối tượng trong một danh sách ... Tôi nghĩ rằng tôi sẽ làm điều đó như thế này:

private List<MyObject<object>> _myList; 

Sau đó tôi muốn tạo một hàm mang theo 1 tham số, là một kiểu dữ liệu , để xem nếu một đối tượng sử dụng datatype đó tồn tại trong danh sách của tôi .... sorta clueless làm thế nào để đi về điều này. Trong Pseudo code nó sẽ là:

public bool Exist(DataType T) 
{ 
    return (does _myList contain a MyObject<T>?); 
} 

Một số làm rõ ....

giao diện của tôi là IMyObject<T>, các đối tượng của tôi là MyObject<T>. Tôi có một lớp mới MyObjectManager mà tôi cần có một Danh sách MyObject<T> được lưu trữ bên trong. Tôi cần một chức năng để kiểm tra xem một MyObject<T> có tồn tại trong danh sách đó hay không. Loại T là các kiểu dữ liệu được tạo tự động bằng cách sử dụng các lớp T4 .... POCO từ Mô hình Dữ liệu Thực thể của tôi.

+0

gì nếu nó có chứa một 'MyObject 'và' U' thừa kế 'T'? – SLaks

+0

U của tôi được tạo tự động bằng các lớp T4 và EF POCO. –

+0

Các lớp có kế thừa lẫn nhau không? – SLaks

Trả lời

6

Bạn có thể thực hiện một chức năng chung:

public bool Exists<T>() where T : class { 
    return _myList.OfType<MyObject<T>>().Any(); 
} 

Lưu ý rằng điều này đòi hỏi bạn phải biết T tại thời gian biên dịch.

Nếu tất cả các bạn có là một đối tượng System.Type khi chạy, bạn sẽ cần phải sử dụng phản ánh:

public bool Exists(Type t) { 
    var objectOfT = typeof(MyObject<>).MakeGenericType(t); 

    return _myList.Any(o => o.GetType() == objectOfT); 
} 

Lưu ý, tuy nhiên, một List<MyObject<object>>không thể tổ chức một MyObject<SomeType>.
Bạn cần thay đổi danh sách thành List<object> hoặc thực hiện MyObject triển khai hoặc kế thừa loại không chung chung và làm cho danh sách chứa loại đó.

+0

Lớp của tôi lưu trữ danh sách sẽ không có kiểu chung, Tuy nhiên, T trong MyObject được biết tại thời gian biên dịch và không gian tên cho các đối tượng này được tham chiếu trong lớp này. Khi tôi thử ví dụ đầu tiên của bạn nó nói Kiểu T phải là một kiểu tham chiếu để sử dụng nó như một tham số. Tôi muốn T là một kiểu generic, vì vậy tôi có thể chuyển vào bất kỳ kiểu dữ liệu nào, cho dù đó là int, string, etc –

+0

Bạn cần thêm một 'Context' lớp, để phù hợp với ràng buộc trong 'MyObject'. – SLaks

+0

OK ... đã phải thêm bool Public Exists () nơi T: class .... thanks! –

0

Vì tất cả đều thực hiện cùng một giao diện, thay vì truyền chúng sang đối tượng và gọi GetType (có thể tốn kém) tại sao không thêm thuộc tính vào giao diện của bạn được gọi là tên lớp (hoặc thứ gì đó)? Sau đó, bạn có thể sử dụng LINQ để lấy thuộc tính đó. Và đừng quên using System.Linq

using System.Linq; 

public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck) 
{ 
    return objects.Any(t => t.ObjectName == typeToCheck.ObjectName); 
} 
+0

Giao diện của tôi là IMyInterface

1

Còn phương pháp khuyến nông thì sao?

public static bool HasAny(this IEnumerable source, Type type) { 
    foreach (object item in source) 
     if (item != null && item.GetType().Equals(type)) 
      return true; 

    return false; 
} 

Cách sử dụng:

bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>)); 

Lưu ý rằng nếu bạn không muốn phải gõ ra typeof(...) - ví dụ, nếu bạn muốn cơ bản của bạn Exist phương pháp để chỉ chăm sóc về các đối tượng của loại MyObject<T>, tôi muốn đi với một cái gì đó giống như câu trả lời của SLaks:

public static bool Exist<T>(this IEnumerable source) { 
    return source.OfType<MyObject<T>>().Any(); 
} 

Ngoài ra, SLaks là đúng mà bạn r eally không thể có một List<MyObject<object>> đó là đầy đủ của bất cứ điều gì khác hơn so với các đối tượng của loại MyObject<object> hoặc một số lớp dẫn xuất (và MyObject<datatype1>, vvlàm không phải có nguồn gốc từ MyObject<object> - generics không hoạt động theo cách đó). Một cách khác tôi có thể đề nghị để làm việc xung quanh toàn bộ "bạn không thể có được loại của một lớp chung bằng cách sử dụng một đối tượng System.Type mà không sử dụng phản ánh" sẽ là: Làm cho MyObject<T> của bạn thực hiện một giao diện không chung chung, như này:

public interface IMyObject { 
    Type DataType { get; } 
} 

public class MyObject<T> : IMyObject<T>, IMyObject { 
    public Type DataType { 
     get { return typeof(T); } 
    } 
} 

Sau đó, danh sách của bạn có thể là một (giao diện phi generic) List<IMyObject> và phương pháp Exist của bạn có thể trông như thế này:

public static bool Exist<T>(this IEnumerable source, Type type) { 
    return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type)); 
} 
Các vấn đề liên quan