Я пытаюсь добиться следующего:
У меня есть интерфейс, называемый IBotCommand , и несколько классов, которые его реализуют. Я хочу найти все эти классы, с помощью отражения, создать экземпляр каждого из них и поместить результат в словарь.
интерфейс выглядит следующим образом:
type IBotCommands =
abstract member Name: unit -> string
abstract member Description: unit -> string
abstract member Help: unit -> string
abstract member Execute: MessageEventArgs -> string[] -> string
и код:
let t = typeof<IBotCommands>
t.Assembly.GetTypes()
|> Seq.filter (fun x -> x.IsSubclassOf(t))
|> Seq.iter (fun x ->
(
let i = Activator.CreateInstance(x) :> IBotCommands
botCommands.[i.Name] <- i
)
)
Проблема, с которой я столкнулся, связана со строкой CreateInstance. CreateInstance возвращает тип obj , который не может быть приведен к IBotCommands.
У меня то же самое в C#, и он работает правильно, но версия C# использует динамику:
public static IEnumerable<Type> FindClassSubclassOfType<T>()
{
var a = typeof(T)
.Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(T)))
.Select(t => t);
return a.ToList();
}
var types = ReflectionHelper.FindClassSubclassOfType<BotCommand>();
foreach (var t in types)
{
dynamic c = Activator.CreateInstance(t);
BotCommands[c.Name] = c;
}
как мне заставить это поведение работать в F #?
можно ли привести объект к интерфейсу в F #? я впервые использую интерфейсы в F #