Я работаю над проблемой уже пару часов, и, кажется, я близок к этому. Я работаю над приложением, в котором у нас может быть 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);
Я немного схитрил, потому что понял, что Func был одинаковым для каждого IDataEntity, так что не было необходимости передавать как параметр для Initialize(). Однако, по крайней мере, теперь я могувызвать Initialize(). Но теперь, когда Func тот же, мне не нужен и общий интерфейс.