代码之家  ›  专栏  ›  技术社区  ›  Code Pope

VB.NET:通过反射实例化嵌套属性

  •  1
  • Code Pope  · 技术社区  · 6 年前

    我想通过反射来设置属性的值。在这 thread 他们提出了解决办法。但解决方案的问题是它没有实例化属性。但如果需要,我想检查并实例化这些属性。我的DTO是:

    Public Class root
        Public Property Printing() As rootPrinting
    End Class
    
    Public Class rootPrinting
        Public Property Printer() As String
        Public Property PrinterBatch() As String
    End Class
    

    现在,为了设置属性,我定义了以下函数:

    Public Sub SetProperty(ByVal target As Object, ByVal compoundProperty As String, ByVal value As Object)
        Dim properties As String() = compoundProperty.Split("."c)
        For i As Integer = 0 To properties.Length - 1 - 1
            Dim propertyToGet As PropertyInfo = target.[GetType]().GetProperty(properties(i))
            target = propertyToGet.GetValue(target, Nothing)
            if IsNothing(target) then
                if propertyToGet.PropertyType.IsClass then
                    target = Activator.CreateInstance(propertyToGet.PropertyType)
                End If
            End If
        Next
    
        Dim propertyToSet As PropertyInfo = target.[GetType]().GetProperty(properties.Last())
        propertyToSet.SetValue(target, value, Nothing)
    End Sub
    

    然后我这样称呼它:

    Dim configObject as New root
    SetProperty(configObject , "Printing.Printer","skjfkd")
    

    如果在呼叫前 SetProperty(configObject,...) 我实例化 configObject.Printing 然后它会很好地工作:

    Dim configObject as New root
    configObject.Printing = new rootPrinting()
    SetProperty(configObject , "Printing.Printer","skjfkd") 
    

    打过电话之后 SetProperty(...) , 配置对象打印 Nothing .
    好像打电话的时候 Activator.CreateInstance(propertyToGet.PropertyType) 对原始对象的引用将丢失。当函数中的对象真正初始化时,主对象仍保留 没有什么 . 如何正确实例化类属性?

    2 回复  |  直到 6 年前
        1
  •  2
  •   David McClelland    6 年前

    这个问题/答案对我很有帮助(谢谢教宗!),我在C中需要相同的代码:

    public void SetProperty(object target, string compoundProperty, object value)
    {
        var properties = compoundProperty.Split('.');
    
        for (int i=0; i < (properties.Length - 1); i++)
        {
            var propertyToGet = target.GetType().GetProperty(properties[i]);
            var property_value = propertyToGet.GetValue(target, null);
            if (property_value == null)
            {
                if (propertyToGet.PropertyType.IsClass)
                {
                    property_value = Activator.CreateInstance(propertyToGet.PropertyType);
                    propertyToGet.SetValue(target, property_value);
                }
            }
            target = property_value;
        }
    
        var propertyToSet = target.GetType().GetProperty(properties.Last());
        propertyToSet.SetValue(target, value);
    }
    
        2
  •  1
  •   Code Pope    6 年前

    好啊。问题解决了。要解决此问题,必须按以下方式修改代码:

    Public Sub SetProperty(ByVal target As Object, ByVal compoundProperty As String, ByVal value As Object)
    
       Dim properties As String() = compoundProperty.Split("."c)
    
       For i As Integer = 0 To properties.Length - 1 - 1
          Dim propertyToGet As PropertyInfo = target.GetType().GetProperty(properties(i))
          Dim property_value = propertyToGet.GetValue(target, Nothing)
          If IsNothing(property_value) Then
             If propertyToGet.PropertyType.IsClass Then
                property_value = Activator.CreateInstance(propertyToGet.PropertyType)
                propertyToGet.SetValue(target, property_value)
             End If
          End If
          target = property_value
       Next
    
       Dim propertyToSet As PropertyInfo = target.GetType().GetProperty(properties.Last())
       propertyToSet.SetValue(target, value)
    
    End Sub