我需要致电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);
}
}
}
答案 0 :(得分:0)
也许你应该将你的可设置属性标记为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];
}
}
答案 1 :(得分:0)
编辑使用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();
}
输出为true,但不完全确定它是否会正确转换所有类型。
答案 2 :(得分:0)
正如其他人所提到的,您应该考虑将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; }
}
}