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

发布于 2024-11-01 23:32:24 字数 1159 浏览 1 评论 0原文

我需要调用 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 的实例

说:

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);
        }
    }
}

I need to call SetSettings() and using the 3 elements in splitSettings, set EncodeAudio to False.
How would I go about doing that? Convert the property of a object to who's name I have in a string.
I realize I could do with with a switch statement of all my settings but there has to be a more dynamic way to go about doing this.

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
   }
}

Yes I have a instance of Settings

Say:

Settings settingManager = new Settings();

I am trying to do is dynamically set EncodeAudo to False by using elements of splitSettings

settingManager.EncodeAudio = False;

Thanks to the help of TBohnen.jnr
I came to this answer:

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);
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡水深流 2024-11-08 23:32:24

编辑使用 int、bool、double 和 string 对其进行了测试,它有效,还添加了一个检查以确保该属性存在并抛出异常(可能想要更改异常类型)

编辑2:临时解决方案,将向转换方法添加更多类型名称,或者如果有人可以建议一种更动态的方式来转换它(如果没有,那么我假设您必须知道所有类型)将被使用)?

EDIT3 从另一个有问题的答案(Chris Taylor)窃取了转换方法,谢谢:-)

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();
}

输出是正确的,但不完全确定它是否会正确转换所有类型。

EDIT Tested it with int, bool, double and string and it worked, also added a check to make sure that the property exists and throws an exception of it doesn't (Might want to change Exception type)

EDIT 2: Temporary solution, will add more typenames to the convert method or alternatively if somebody can suggest a more dynamic way of casting it (If not then I assume you will have to know all of the types that will be used)?

EDIT3 Stole the convert method from another answer in question (Chris Taylor ), thanks :-)

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);

    }

Taken from http://www.haslo.ch/blog/setproperty-and-getproperty-with-c-reflection/

Was interested to see if this works, create a quick test:

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();
}

The output is true, not entirely sure if it will convert all types correctly though.

落日海湾 2024-11-08 23:32:24

正如其他人提到的,您应该考虑将 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; }    
  }
}

As others have mentioned, you should consider making your SettingsLib class static. And you might also need to handle the conversion of values from strings to the target types. Here is a simple example how this would work.

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; }    
  }
}
输什么也不输骨气 2024-11-08 23:32:24

也许您应该将可设置属性标记为静态,然后尝试使用反射设置值:

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];
   }
}

Maybe you should mark your settable properties as static and then try to set the values using 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];
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文