简体   繁体   English

如何从父 class 中的名称动态设置属性?

[英]How do I Dynamically set properties from the name in a parent class?

How do I dynamically set the "Name" properties of each of the AlarmModel's as the name of the model (ie HardwareFault) from the parent class?如何从父 class 动态地将每个 AlarmModel 的“名称”属性设置为 model(即 HardwareFault)的名称?

public class NotificationModel
{
    public string UnrelatedProperty { get; set; }  // any solution should ignore other properties.

    public AlarmModel HardwareFault{ get; set; }

    public AlarmModel TimeoutFault { get; set; }

    public AlarmModel GenericFault { get; set; }
}

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

    public bool isActive { get; set; }

    public bool isEnabled { get; set; }

    public bool isSilenced { get; set; }
}

You should move property "Name" to parent class.您应该将属性“名称”移动到父 class。 and try to extend/inherit it to child class.并尝试将其扩展/继承给子 class。

If I understand correctly, you want to set the Name property of each AlarmModel to the name of the property in the parent NotificationModel ?如果我理解正确,您想将每个AlarmModelName属性设置为父NotificationModel中的属性名称吗?

If that is the case, you could do something like this:如果是这种情况,您可以执行以下操作:

public class NotificationModel
{
    private AlarmModel _hardwareFault;

    private AlarmModel _timeoutFault;

    private AlarmModel _genericFault;

    public string UnrelatedProperty { get; set; }  // any solution should ignore other properties.

    public AlarmModel HardwareFault
    { 
        get => _hardwareFault; 
        set
        {
            _hardwareFault = value;
            SetName(value);
        }
    }

    public AlarmModel TimeoutFault 
    {
        get => _timeoutFault; 
        set
        {
            _timeoutFault= value;
            SetName(value);
        }
    }

    public AlarmModel GenericFault 
    {
        get => _genericFault; 
        set
        {
            _genericFault= value;
            SetName(value);
        }
    }

    private SetName(AlarmModel model, [CallerMemberName] string propertyName = null)
    {
        model.Name = propertyName;
    }
}

If you have already initialized NotificationModel with also already initialized HardwareFault , TimeoutFault , GenericFault properties, you can use this example:如果您已经使用已经初始化的HardwareFaultTimeoutFaultGenericFault属性初始化了NotificationModel ,则可以使用此示例:

var notificationModel = new NotificationModel()
{
    HardwareFault = new AlarmModel(),
    GenericFault = new AlarmModel(),
    TimeoutFault = new AlarmModel()
};

notificationModel?.GetType().GetProperties().Where(p => p.PropertyType.Name == "AlarmModel") // Or p.PropertyType == typeof(AlarmModel)
                                            .ToList().ForEach(alarmModelProperty =>
{
    // Get AlarmModel property instance
    var alarmModelInstance = alarmModelProperty.GetValue(notificationModel);
    // Get Name property
    var nameProperty = alarmModelIntance?.GetType().GetProperty("Name");
    // Set Name property value with name of AlarmModel property
    nameProperty?.SetValue(alarmModelInstance, alarmModelProperty.Name);
});

If you have already initialized NotificationModel , but without initialized HardwareFault , TimeoutFault , GenericFault properties, you can use this example:如果您已经初始化NotificationModel ,但没有初始化HardwareFaultTimeoutFaultGenericFault属性,则可以使用此示例:

var notificationModel = new NotificationModel();

notificationModel?.GetType().GetProperties().Where(p => p.PropertyType.Name == "AlarmModel") // Or p.PropertyType == typeof(AlarmModel)
                                            .ToList().ForEach(alarmModelProperty =>
{
    // Initialize new AlarmModel 
    var alarmModelInstance = Activator.CreateInstance(alarmModelProperty.PropertyType);
    // Get Name property of AlarmModel
    var nameProperty = alarmModelInstance.GetType().GetProperty("Name");
    // Set Name property of AlarmModel
    nameProperty?.SetValue(alarmModelInstance, alarmModelProperty.Name);
    // Set AlarmModel property of NotificationModel
    alarmModelProperty.SetValue(notificationModel, alarmModelInstance);
});

If you need full initialization with Reflection, you can use this example:如果您需要使用反射进行完全初始化,可以使用以下示例:

var notificationModelType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(type => type.Name == "NotificationModel"); // Or type == typeof(NotificationModel)
if (notificationModelType is null) // No NotificationModel found in current assembly
    return;

// Initializing NotificationModel
var notificationModel = Activator.CreateInstance(notificationModelType);

notificationModel?.GetType().GetProperties().Where(p => p.PropertyType.Name == "AlarmModel") // Or p.PropertyType == typeof(AlarmModel)
                                            .ToList().ForEach(alarmModelProperty =>
{
    // Initialize new AlarmModel 
    var alarmModelInstance = Activator.CreateInstance(alarmModelProperty.PropertyType);
    // Get Name property of AlarmModel
    var nameProperty = alarmModelInstance.GetType().GetProperty("Name");
    // Set Name property of AlarmModel
    nameProperty?.SetValue(alarmModelInstance, alarmModelProperty.Name);
    // Set AlarmModel property of NotificationModel
    alarmModelProperty.SetValue(notificationModel, alarmModelInstance);
});

If NotificationModel declared NOT in current assembly (so it won't be in Assembly.GetExecutingAssembly().GetTypes() ) - you can search through all loaded assemblies in AppDomain.CurrentDomain :如果NotificationModel声明不在当前程序集中(因此它不会在Assembly.GetExecutingAssembly().GetTypes()中) - 您可以在AppDomain.CurrentDomain中搜索所有已加载的程序集:

var notificationModelType = AppDomain.CurrentDomain.GetAssemblies()
                                                   .SelectMany(assembly => assembly.GetTypes())
                                                   .FirstOrDefault(type => type.Name == "NotificationModel");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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