Tôi đã làm việc thông qua một vấn đề trong một vài giờ, và tôi nghĩ rằng tôi gần gũi. Tôi đang làm việc trên một ứng dụng mà chúng tôi có thể có 50-100 loại thực hiện theo cùng một cách. Vì vậy, thay vì tạo 50-100 lớp học, tôi đã cố gắng để làm cho nó chung chung và đây là những gì tôi có:Tạo Kiểu Chung với Giao diện Chung tại Thời gian Chạy
Đây là lớp cơ sở:
public class RavenWriterBase<T> : IRavenWriter<T> where T : class, IDataEntity
Và đây là giao diện:
public interface IRavenWriter<T>
{
int ExecutionIntervalInSeconds { get; }
void Execute(object stateInfo);
void Initialize(int executionIntervalInSeconds, Expression<Func<T, DateTime>> timeOrderByFunc);
}
Và đây là cách tôi đang sử dụng nó:
private static void StartWriters()
{
Assembly assembly = typeof(IDataEntity).Assembly;
List<IDataEntity> dataEntities = ReflectionUtility.GetObjectsForAnInterface<IDataEntity>(assembly);
foreach (IDataEntity dataEntity in dataEntities)
{
Type dataEntityType = dataEntity.GetType();
Type ravenWriterType = typeof(RavenWriterBase<>).MakeGenericType(dataEntityType);
Expression<Func<IDataEntity, DateTime>> func = x => x.CicReadTime;
// This is where I'm stuck. How do I activate this as RavenWriterBase<T>?
var ravenWriter = Activator.CreateInstance(ravenWriterType);
//ravenWriter.Initialize(60, func); // I can't do this until I cast.
// More functionality here (not part of this issue)
}
}
tôi bị mắc kẹt trên đường dây này từ trên cao:
var ravenWriter = Activator.CreateInstance(ravenWriterType);
Đây là câu hỏi của tôi:
Làm thế nào tôi có thể sử dụng như RavenWriterBase hoặc IRavenWriter? Một cái gì đó như:
ravenWriter.Initialize(60, func);
Tôi nghĩ rằng nó cần phải được một cái gì đó như thế này, nhưng tôi cần phải xác định một kiểu cho IRavenWriter <> và tôi không biết nó được nêu ra:
var ravenWriter = Activator.CreateInstance(ravenWriterType) as IRavenWriter<>;
Nếu tôi di chuột qua ravenWriter, tôi thành công có đối tượng của tôi:
Nhưng bây giờ tôi cần để có thể sử dụng nó trong một cách chung chung. Làm thế nào tôi có thể làm điều đó?
Cập nhật:
tôi chỉ nghĩ đến việc sử dụng từ khóa năng động, và các công trình này:
dynamic ravenWriter = Activator.CreateInstance(ravenWriterType);
ravenWriter.Initialize(60);
tôi lừa một chút vì tôi nhận ra rằng Func là như nhau đối với từng IDataEntity, vì vậy không cần thiết để chuyển thành tham số khởi tạo(). Tuy nhiên, ít nhất bây giờ tôi có thể gọi khởi tạo(). Nhưng bây giờ Func là như nhau, tôi cũng không cần giao diện chung.
Nghe có vẻ như sử dụng không đúng các loại thuốc generic. Khi bạn thấy mình cần chạy các phương thức khác nhau dựa trên các kiểu khác nhau, nhưng các kiểu chỉ được biết khi chạy, bạn muốn sử dụng đa hình. Các generics là gì? Bạn có thể chạy các phương thức như là không có generics ở nơi đầu tiên, tức là, với IDataEntity? – mellamokb
Tôi đồng ý với mellamokb. Tuy nhiên, nếu bạn được thiết lập trên generics, tại sao không tạo ra một lớp wrapper mà bạn có thể nhanh chóng non-genarically. Trình bao bọc phải có phương thức trả về một cá thể của RavenWriterBase tùy thuộc vào loại được truyền vào như một đối số. Sau đó, khởi tạo trình bao bọc và gọi phương thức với kiểu được yêu cầu làm tham số. Điều này sẽ đòi hỏi một tuyên bố chuyển đổi lớn, nhưng ít nhất không phải 200 lớp riêng biệt. –
dcow
Bạn có tạo các Biểu thức khác không sử dụng IDataEntity cho T không? Hoặc là T luôn luôn là một IDataEntity? Và nếu T luôn là IDataEntity, tại sao lại sử dụng Generics? –