繁体   English   中英

C#创建从泛型类型派生的已加载类型的实例

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM