c# - 如何在 C# 中正确实例化动态派生对象及其成员

标签 c# inheritance

我目前在 C# 中遇到了一个看似基本的问题。我想动态实例化一个 C# 类。它应该是基类或派生类。 我的问题是,当我尝试实例化派生类并设置对象的属性时,属性始终为空。这是 LINQ-Pad 片段:

void Main()
{
    var baseProperty = new BaseProperty() { Name = "TestName" };
    // this one is working, meaning the member Properties != null
    var baseObject = GetObjectInstance<BaseClass, BaseProperty>(baseProperty);
    baseObject.Properties.Dump();

    var derivedProperty = new DerivedProperty() { Name = "TestName", Description = "TestDescription" };
    // this one is not working, meaning derivedObject.Properties is always null
    var derivedObject = GetObjectInstance<DerivedClass, DerivedProperty>(derivedProperty);
    derivedObject.Properties.Dump();
}

public class BaseClass
{
    public BaseProperty Properties { get; set; }
}

public class DerivedClass : BaseClass
{
    public new DerivedProperty Properties { get; set; }
}

public class BaseProperty
{
    public string Name { get; set; }
}

public class DerivedProperty : BaseProperty
{
    public string Description { get; set; }
}


public TClass GetObjectInstance<TClass, TProperty>(TProperty properties) 
    where TClass : BaseClass 
    where TProperty : BaseProperty
{
    var myObject = Activator.CreateInstance<TClass>();
    myObject.Properties = properties; // this member is always null
    return myObject;
}

一旦我实例化衍生对象并尝试设置DerivedProperty类型的衍生属性,该属性就为空。

我哪里错了?我该如何解决这个问题?有人有想法吗?

最佳答案

您正在使用 new 隐藏您的属性(property)修饰符。这意味着当您调用基类型上的属性时,它与派生类型上的属性不同。您可能希望使用泛型来指定属性的类型。例如:

public class BaseClass<TProperty> 
    where TProperty : BaseProperty
{
    // Now we have a generic property that must be a BaseProperty
    public TProperty Properties { get; set; }
}

public class DerivedClass : BaseClass<DerivedProperty>
{
    // No need for any specific override here any more
}

并对您的功能进行一些细微的调整:

public TClass GetObjectInstance<TClass, TProperty>(TProperty properties)
    where TClass : BaseClass<TProperty>
    where TProperty : BaseProperty
{
    var myObject = Activator.CreateInstance<TClass>();
    myObject.Properties = properties;
    return myObject;
}

您可能需要考虑的另一件事是使用 new() 约束,这意味着您不再需要使用 Activator.CreateInstance:

public TClass GetObjectInstance<TClass, TProperty>(TProperty properties)
    where TClass : BaseClass<TProperty>, new()
    where TProperty : BaseProperty
{
    var myObject = new TClass();
    myObject.Properties = properties;
    return myObject;
}

关于c# - 如何在 C# 中正确实例化动态派生对象及其成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58239392/

相关文章:

javascript - 三个按钮从 Controller 调用相同的操作方法 - 确定调用哪一个方法

c++ - 使用模板和继承的容器实现

java - 理解类成员行为多态性

c++ - 如何让一组不同的子类对象共享另一组基类的一个静态变量?

c# - 比 boyer moore 算法更快的字符串搜索方法?

c# - ValueType.GetHashCode 的 native 实现如何工作?

c# - Web Api/ASP.NET Windows 身份验证如何工作?

c++ - 如何使用指向基类c++的指针在派生类中创建属性

c++ - 构造函数继承和自定义构造函数

c# - 将事件查看器日志文件导出为 *.evtx 文件