将对象名称空间和名称转换为对象

| 我需要调用
SetSettings()
并使用
splitSettings
中的3个元素,将
EncodeAudio
设置为
False
。 我将如何去做?将对象的属性转换为我在字符串中具有的姓名。 我意识到我可以使用所有设置的switch语句来做,但是必须有一种更动态的方式来执行此操作。
namespace SettingsLib
{
  public class Settings
  {
    public Boolean EncodeAudio { get; set; }
  }
}
namespace Service
{
   void SetSettings()
   {
     string[] splitSettings = { \"SettingsLib.Settings\", \"EncodeAudio\", \"False\" };
     // Need to set EncodeAudio to False in SettingsLib.Settings
   }
}
是的,我有一个设置实例 说:
Settings settingManager = new Settings();
我正在尝试通过使用splitSettings的元素将EncodeAudo动态设置为False
settingManager.EncodeAudio = False;
感谢TBohnen.jnr的帮助 我来到这个答案:
public void setProperty(object containingObject, string propertyName, object newValue)
{
    foreach (PropertyInfo p in containingObject.GetType().GetProperties())
    {
        if (p.Name == propertyName)
        {
            p.SetValue(containingObject, Convert.ChangeType(newValue, p.PropertyType), null);
        }
    }
}
    
已邀请:
EDIT使用int,bool,double和string对其进行了测试,并且可以正常工作,还添加了一个检查以确保该属性存在并引发不存在的异常(可能要更改Exception类型) 编辑2:临时解决方案,是否将更多类型名称添加到convert方法,或者如果有人可以建议一种更动态的类型转换(如果不是,那么我认为您将必须知道将要使用的所有类型)? EDIT3从另一个有问题的答案(Chris Taylor)中偷走了convert方法,谢谢:-)
public void setProperty(object containingObject, string propertyName, object newValue)
    {
        if (containingObject.GetType().GetProperties().Count(c => c.Name == propertyName) > 0)
        {
            var type = containingObject.GetType().GetProperties().First(c => c.Name == propertyName).PropertyType;
            object val = Convert(type,(string)newValue);
            containingObject.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, containingObject, new object[] { val });
        }
        else
        {
            throw new KeyNotFoundException(\"The property: \" + propertyName + \" was not found in: \" + containingObject.GetType().Name);
        }
    }

    public object convert(System.Type type, string value)
    {
        return Convert.ChangeType(value, type);

    }
取自http://www.haslo.ch/blog/setproperty-and-getproperty-with-c-reflection/ 有兴趣查看是否可行,请创建一个快速测试:
class testSettings
{
    public bool SetBool { get; set; }

    public void setProperty(object containingObject, string propertyName, object newValue) 
    {
         if (containingObject.GetType().GetProperties().Count(c => c.Name == propertyName) > 0)
        {
            containingObject.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, containingObject, new object[] { newValue });
        }
        else
        {
            throw new KeyNotFoundException(\"The property: \" + propertyName + \" was not found in: \" + containingObject.GetType().Name);
        }
    }
}

static void Main(string[] args)
{
    testSettings ts = new testSettings();
    ts.SetBool = false;
    ts.setProperty(ts, \"SetBool\", true);
    Console.WriteLine(ts.SetBool.ToString());
    Console.Read();
}
输出为true,但不确定是否会正确转换所有类型。     
正如其他人提到的那样,您应该考虑将SettingsLib类设为静态。而且,您可能还需要处理从字符串到目标类型的值转换。这是一个简单的例子。
namespace Service
{
  class Program
  {
    static void Main(string[] args)
    {
      string[] splitSettings = { \"SettingsLib.Settings\", \"EncodeAudio\", \"False\" };
      SetProperty(splitSettings[0], splitSettings[1], splitSettings[2]);  
    }

    static void SetProperty(string typeName, string propertyName, object value)
    {
      var type = Type.GetType(typeName);
      if (type == null) 
      {
        throw new ArgumentException(\"Unable to get type\", \"typeName\");
      }

      var pi = type.GetProperty(propertyName);
      if (pi == null) 
      {
        throw new ArgumentException(\"Unable to find property on type\", \"propertyName\");
      }

      object propertyValue = value;

      if (propertyValue != null)
      {
        // You might need more elaborate testing here to ensure that you can handle 
        // all the various types, you might need to special case some types here 
        // but this will work for the basics.
        if (pi.PropertyType != propertyValue.GetType())
        {
          propertyValue = Convert.ChangeType(propertyValue, pi.PropertyType);
        }
      }

      pi.SetValue(null, propertyValue, null);
    }
  }
}

namespace SettingsLib
{
  public static class Settings
  {
    public static bool EncodeAudio { get; set; }    
  }
}
    
也许您应该将可设置的属性标记为
static
,然后尝试使用Reflection设置值:
namespace SettingsLib
{
  public static class Settings
  {
    public static bool EncodeAudio { get; set; }
  }
}
namespace Service
{
   void SetSettings()
   {
     string[] splitSettings = { \"SettingsLib.Settings\", \"EncodeAudio\", \"False\" };
     dynamic property = Type.GetType(splitSettings[0]).GetProperty(splitSettings[1]);
     property = splitSettings[2];
   }
}
    

要回复问题请先登录注册