[英]Create an interface with a method that's 'generic', but it's generic type is the implementer of the interface
[英]Create Generic Type with Generic Interface at Run Time
我現在已經解決了幾個小時的問題,我想我很接近。 我正在開發一個應用程序,我們可以有50-100種類型,執行相同的方式。 因此,我沒有創建50-100個類,而是試圖使它成為通用的,這就是我所擁有的:
這是基類:
public class RavenWriterBase<T> : IRavenWriter<T> where T : class, IDataEntity
這是界面:
public interface IRavenWriter<T>
{
int ExecutionIntervalInSeconds { get; }
void Execute(object stateInfo);
void Initialize(int executionIntervalInSeconds, Expression<Func<T, DateTime>> timeOrderByFunc);
}
這就是我使用它的方式:
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)
}
}
我從上面堅持這條線:
var ravenWriter = Activator.CreateInstance(ravenWriterType);
這是我的問題:
我如何將其用作RavenWriterBase或IRavenWriter? 就像是:
ravenWriter.Initialize(60, func);
我認為它需要像這樣,但我需要為IRavenWriter <>指定一個類型,我還不知道它:
var ravenWriter = Activator.CreateInstance(ravenWriterType) as IRavenWriter<>;
如果我將鼠標懸停在ravenWriter上,我就成功擁有了我的對象:
但現在我需要能夠以通用的方式使用它。 我怎樣才能做到這一點?
更新:
我只想到使用動態關鍵字,這有效:
dynamic ravenWriter = Activator.CreateInstance(ravenWriterType);
ravenWriter.Initialize(60);
我作弊了一點,因為我意識到每個IDataEntity的Func是相同的,所以沒有必要作為參數傳遞給Initialize()。 但是,至少現在我可以調用Initialize()。 但是現在Func是相同的,我也不需要通用接口。
我的解決方案是:
IRavenWriter
的非泛型接口 IRavenWriter<T>
繼承自IRavenWriter
IRavenWriter
保持Execute
和ExecutionIntervalInSeconds
IRavenWriter
具有Func<DateTime>
並在您的IRavenWriter
使用它 Initialize
移動到IRavenWriter<T>
例如:
public class MyDateTime
{
public DateTime This { get; set; }
}
public static Func<DateTime> GetFunk<T>(Expression<Func<T, DateTime>> timeOrderByFunc, T t)
{
return () => timeOrderByFunc.Compile()(t);
}
你使用:
GetFunk<MyDateTime>(x => x.This, new MyDateTime(){This = DateTime.Now});
將運行時Type
轉換為編譯時通用類型參數並不是很困難。 只需介紹用於創建/初始化對象的新界面:
interface IRawenWriterFactory
{
object Create();
}
class RawenWriterFactory<T> : IRawenWriterFactory
{
public object Create()
{
Expression<Func<IDataEntity, DateTime>> func = x => x.CicReadTime;
var ravenWriter = new RavenWriterBase<T>();
ravenWriter.Initialize(60, func);
return ravenWriter;
}
}
現在只需使用dataEntityType創建RawenWriterFactory
就像您創建了ravenWriter
並通過非泛型IRavenWriterFactory接口使用它一樣。
但是,如果您改變設計,可能會有更簡單的解決方案。 例如,如果將Initialize方法轉換為構造函數,則可以將func作為Activator.CreateInstance參數傳遞,並且根本不需要使用通用接口進行初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.