[英]C# create instance of loaded type derivied from generic type
我的SDK中没有几个类和接口:
public interface IUser
{
string Name { get; set; }
}
public abstract class SettingsBase<TUser> where TUser : IUser
{
public ObservableCollection<TUser> Users { get; set; }
}
public abstract class Page<TUser> where TUser : IUser
{
public SettingsBase<TUser> Settings { get; set; }
}
我有一个带有公共类的.dll库:
public class ConfigPage : Page<User>
{
}
public class User : IUser
{
public string Name { get; set; }
}
public class Settings : SettingsBase<User>
{
private int _additionalSetting;
}
我想检查.dll是否具有从Page派生的ConfigPage类:
var dll = Assembly.LoadFrom(@"libraryName.dll");
var type = dll.GetExportedTypes().FirstOrDefault(t => t.Name == "ConfigPage"); // the type is Page<User>
var isIUser = type.BaseType.GetGenericArguments()[0].GetInterfaces().Contains(typeof(IUser));
好的,一切都很好,但是最后我的问题是:
如何获取对SettingsBase Settings属性的访问?
为什么此返回null? :
Activator.CreateInstance(type) as Page<IUser> // type is Page<User>, User implement IUser
强制转换结果为null
的原因是事实,即泛型类是不变的 -您不能将MyClass<Base>
的实例分配给MyClass<Derived>
类型的变量,反之亦然。
我建议您使用interfaces-covariance更新接口:
public interface IUser {
string Name { get; set; }
}
public interface ISettings<out TUser>
where TUser : IUser {
IEnumerable<TUser> Users { get; }
}
public interface IPage<out TUser>
where TUser : IUser {
ISettings<TUser> Settings { get; }
}
// Abstract implementation
public abstract class SettingsBase<TUser> : ISettings<TUser
where TUser : IUser {
public SettingsBase() {
Users = new ObservableCollection<TUser>();
}
public IEnumerable<TUser> Users { get; private set; }
}
public abstract class Page<TUser> : IPage<TUser>
where TUser : IUser {
public Page() {
Settings = CreateSettings();
}
public ISettings<TUser> Settings { get; private set; }
//
protected abstract ISettings<TUser> CreateSettings();
}
// Real implementation
public class ConfigPage : Page<User> {
protected override ISettings<User> CreateSettings() {
return new Settings();
}
}
public class User : IUser {
public string Name { get; set; }
}
public class Settings : SettingsBase<User> {
// ...
}
用法:
IPage<IUser> page = Activator.CreateInstance(typeof(ConfigPage)) as IPage<IUser>;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.