C# 使用反射设置嵌套特性值
我找遍了,但找不到我问题的确切答案。以以下代码为例:C# 使用反射设置嵌套特性值,c#,.net,reflection,C#,.net,Reflection,我找遍了,但找不到我问题的确切答案。以以下代码为例: public class Company { private string m_strName; private Customer m_objCustomer; public Company() { m_strName = ""; m_objCustomer = new Customer(); } public string Name {
public class Company
{
private string m_strName;
private Customer m_objCustomer;
public Company()
{
m_strName = "";
m_objCustomer = new Customer();
}
public string Name
{
get { return m_strName; }
set { m_strName = value; }
}
public Customer CustomerInformaion
{
get { return m_objCustomer; }
set { m_objCustomer = value; }
}
}
public class Customer
{
private string m_strName;
private Details m_objDetails;
public Customer()
{
m_strName = "";
m_objDetails = new Details();
}
public string Name
{
get { return m_strName; }
set { m_strName = value; }
}
public Details CustomerDetails
{
get { return m_objDetails; }
set { m_objDetails = value; }
}
}
public class Details
{
private string m_strPhoneNumber;
private string m_strEmailAddress;
public Details()
{
m_strPhoneNumber = "";
m_strEmailAddress = "";
}
public string PhoneNumber
{
get { return m_strPhoneNumber; }
set { m_strPhoneNumber = value; }
}
public string EmailAddress
{
get { return m_strEmailAddress; }
set { m_strEmailAddress = value; }
}
}
现在,我设置了一个表单,其中有许多文本字段,用户可以在其中输入有关公司客户的信息。其中一个字段是电子邮件地址文本字段,其标记属性设置为EmailAddress。我希望能够查看TextBox的标记并遍历整个Company对象,找到具有匹配名称的属性,并将其值设置为TextBox的Text属性。我可以找到该属性,但设置其值却非常困难。到目前为止,我所掌握的情况如下:
foreach (PropertyInfo info in m_objCompany.GetType().GetProperties())
{
if (info.PropertyType != typeof(System.String))
{
foreach (PropertyInfo info2 in info.PropertyType.GetProperties())
{
if (objTextBox.Tag.Equals(info2.Name))
{
if (info2.CanWrite)
{
Object objValue = Convert.ChangeType(objTextBox.Text, info.PropertyType);
info2.SetValue(m_objCompany, objValue, null);
}
}
}
}
}
我的问题是,当我运行代码时,我在ChangeType和/或SetValue处收到一个错误。问题是反射正在info2处停止,并试图将值设置为详细信息的类型,因为它是属性EmailAddress的父级
在确定如何将SetValue指向适当的属性时提供的任何帮助都会很有帮助,我们将不胜感激。我相信您可以猜到,我的类比提供了近100个属性的示例要大得多。大多数都是字符串值,将通过TextBox对象手动输入。我试图创建一个例程,所有TextBox对象都可以调用该例程,通过该例程,可以使用对象的Tag属性来指示我试图设置的类的哪个属性。从这里开始,它就进入了XML序列化领域。您的最内层
info2.SetValue(m_objCompany, objValue, null);
正在尝试设置外部对象的内部属性(info2)的值。外部对象没有内部对象
你可能想要的是这样的:
public void Bar(object m_objCompany)
{
foreach (PropertyInfo info in m_objCompany.GetType().GetProperties())
{
if (info.PropertyType != typeof(System.String))
{
// Somehow create the outer property
object outerPropertyValue = info.PropertyType.GetConstructor(new Type[] { }).Invoke(new object[] { });
foreach (PropertyInfo info2 in info.PropertyType.GetProperties())
{
if ("blah" == "blah")
{
if (info2.CanWrite)
{
Object innerPropertyValue = Convert.ChangeType("blah", info2.PropertyType);
info2.SetValue(outerPropertyValue, innerPropertyValue, null);
}
}
}
info.SetValue(m_objCompany, outerPropertyValue, null);
}
}
}
当您遇到要设置的属性时,需要创建该属性(outerPropertyValue),然后设置该属性的属性(通过innerPropertyValue),然后在原始对象(m_objCompany)上设置outer属性。以下是我用于反射的一些代码。在这种情况下,您需要调用
SetValue
方法
Reflector.SetValue(TARGET_OBJECT, "Customer.Details.PhoneNumber", "ValueToSet");
更新:添加了缺少的ConversionResult结构。对不起,遗漏了
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
namespace YourNamespace
{
public struct ConversionResult
{
public Boolean Success;
public object ConvertedValue;
}
public static class Reflector
{
private static BindingFlags DefaultBindings = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic;
#region Public Methods
/// <summary>
/// Execute the "codeToExecute" string on the "source" object
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="codeToExecute">Code that should be executed ex. 'Person.Age'</param>
/// <returns>The result of execute codeToExecute on source</returns>
public static object GetValue(object source, String codeToExecute)
{
ReflectorResult reflectorResult = GetReflectorResult(source, codeToExecute, true, false);
if (reflectorResult != null)
{
return reflectorResult.Value;
}
return null;
}
/// <summary>
/// Sets the "source" object to the "value" specified in "codeToExecute"
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="codeToExecute">Code that should be executed ex. 'Person.Age'</param>
/// <param name="value">Value to set the source+codeToExecute to.</param>
public static Boolean SetValue(object source, String codeToExecute, object value)
{
return SetValue(source, codeToExecute, value, false);
}
/// <summary>
/// Sets the "source" object to the "value" specified in "codeToExecute"
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="codeToExecute">Code that should be executed ex. 'Person.Age'</param>
/// <param name="value">Value to set the source+codeToExecute to.</param>
/// <param name="createIfNotExists">Creates items it cannot find</param>
public static Boolean SetValue(object source, String codeToExecute, object value, Boolean createIfNotExists)
{
Boolean executed = true;
ReflectorResult reflectorResult = GetReflectorResult(source, codeToExecute, false, createIfNotExists);
if (reflectorResult != null)
{
TypeConverter typeConverter = null;
PropertyInfo propertyInfo = reflectorResult.MemberInfo as PropertyInfo;
if (propertyInfo != null)
{
if (propertyInfo.CanWrite)
{
typeConverter = GetTypeConverter(propertyInfo);
ConversionResult conversionResult = ConvertValue(value, propertyInfo.PropertyType, typeConverter);
if (conversionResult.Success)
{
propertyInfo.SetValue(reflectorResult.PreviousValue, conversionResult.ConvertedValue, reflectorResult.MemberInfoParameters);
}
else
{
executed = false;
PentaLogger.LogVerbose("Invalid value: " + value);
}
}
}
else
{
FieldInfo fieldInfo = reflectorResult.MemberInfo as FieldInfo;
if (fieldInfo != null)
{
typeConverter = GetTypeConverter(fieldInfo);
ConversionResult conversionResult = ConvertValue(value, fieldInfo.FieldType, typeConverter);
if (conversionResult.Success)
{
fieldInfo.SetValue(reflectorResult.PreviousValue, conversionResult.ConvertedValue);
}
else
{
executed = false;
PentaLogger.LogVerbose("Invalid value: " + value);
}
}
else
{
// both property and field are invalid
executed = false;
}
}
}
else
{
executed = false;
}
return executed;
}
/// <summary>
/// Sets the "source" object to the "value" specified in "codeToExecute"
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="codeToExecute">Code that should be executed ex. 'Person.Age'</param>
/// <param name="value">Value to set the source+codeToExecute to.</param>
public static void RunDynamicCode(object source, String codeToExecute)
{
GetReflectorResult(source, codeToExecute, true, false);
}
/// <summary>
/// Executes the method on the "source" object with the passed parameters
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="methodName">Method to call</param>
/// <param name="parameters">Method Parameters</param>
public static object ExecuteMethod(object source, String methodName, object[] parameters)
{
if (parameters == null)
{
parameters = new object[0];
}
MethodInfo[] methodInfos = GetMethods(source, methodName);
foreach (MethodInfo methodInfo in methodInfos)
{
object[] convertedParameters = GetParameters(methodInfo, parameters);
if (convertedParameters != null)
{
return methodInfo.Invoke(source, convertedParameters);
}
}
return null;
}
/// <summary>
/// Executes the method on the "source" object with the passed parameters
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="methodName">Method to call</param>
/// <param name="parameter">Method Parameter</param>
public static object ExecuteMethod(object source, String methodName, object parameter)
{
return ExecuteMethod(source, methodName, new object[] { parameter });
}
/// <summary>
/// Executes the method on the "source" object with no parameters
/// </summary>
/// <param name="source">Object the code should be executed against</param>
/// <param name="methodName">Method to call</param>
public static object ExecuteMethod(object source, String methodName)
{
return ExecuteMethod(source, methodName, null);
}
/// <summary>
/// Copies all public properties and fields from source to target
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
public static void CopyObject(object source, object target)
{
if (source != null && target != null)
{
Type targetType = target.GetType();
Type sourceType = source.GetType();
PropertyInfo[] properties = sourceType.GetProperties(DefaultBindings);
foreach (PropertyInfo sourceProperty in properties)
{
PropertyInfo targetProperty = targetType.GetProperty(sourceProperty.Name, sourceProperty.PropertyType);
if (targetProperty != null && targetProperty.CanRead && targetProperty.CanWrite)
{
object value = sourceProperty.GetValue(source, null);
targetProperty.SetValue(target, value, null);
}
}
FieldInfo[] fields = sourceType.GetFields(DefaultBindings);
foreach (FieldInfo sourceField in fields)
{
FieldInfo targetField = targetType.GetField(sourceField.Name);
if (targetField != null && targetField.IsPublic)
{
object value = sourceField.GetValue(source);
targetField.SetValue(target, value);
}
}
}
}
/// <summary>
/// Convert the object to the correct type
/// </summary>
/// <param name="value">Value to convert</param>
/// <param name="type">Type to convert to</param>
/// <returns>Converted value</returns>
public static ConversionResult ConvertValue(object value, Type type, TypeConverter typeConverter)
{
ConversionResult conversionResult = new ConversionResult();
conversionResult.Success = false;
if (value != null && type != null)
{
Type objectType = value.GetType();
if (objectType == type)
{
conversionResult.Success = true;
conversionResult.ConvertedValue = value;
}
else
{
// If there is an explicit type converter use it
if (typeConverter != null && typeConverter.CanConvertFrom(objectType))
{
try
{
conversionResult.ConvertedValue = typeConverter.ConvertFrom(value);
conversionResult.Success = true;
}
catch (FormatException) { }
catch (Exception e)
{
if (!(e.InnerException is FormatException))
{
throw;
}
}
}
else
{
try
{
conversionResult.ConvertedValue = Convert.ChangeType(value, type, CultureInfo.CurrentCulture);
conversionResult.Success = true;
}
catch (InvalidCastException) { }
}
}
}
return conversionResult;
}
public static Boolean CanCreateObect(String classPath, Assembly assembly, params object[] parameters)
{
Boolean canCreate = false;
Type type = Type.GetType(classPath);
if (type == null)
{
String pathWithAssembly = classPath + ", " + assembly.FullName;
type = Type.GetType(pathWithAssembly);
}
if (type != null)
{
foreach (ConstructorInfo ci in type.GetConstructors())
{
if (ci.IsPublic)
{
ParameterInfo[] constructorParameters = ci.GetParameters();
if (constructorParameters.Length == parameters.Length)
{
for(Int32 i=0; i<constructorParameters.Length; i++)
{
object parameter = parameters[i];
if(parameter == null)
{
continue;
}
ParameterInfo pi = constructorParameters[i];
if (!pi.ParameterType.IsAssignableFrom(parameter.GetType()))
{
break;
}
}
canCreate = true;
break;
}
}
}
}
return canCreate;
}
public static object CreateObject(String classPath, Assembly assembly, params object[] parameters)
{
Type type = Type.GetType(classPath);
if (type == null)
{
String pathWithAssembly = classPath + ", " + assembly.FullName;
type = Type.GetType(pathWithAssembly);
}
if (type == null)
{
return null;
}
return Activator.CreateInstance(type, parameters);
}
#endregion
#region Private Methods
private static ReflectorResult GetReflectorResult(object source, String codeToExecute, bool getLastValue, bool createIfNotExists)
{
ReflectorResult result = new ReflectorResult(source);
try
{
// Split the code into usable fragments
String[] codeFragments = SplitCodeArray(codeToExecute);
for (Int32 i = 0; i < codeFragments.Length; i++)
{
// if the value is null we cannot go any deeper so don't waste your time
if (result.Value == null)
{
return result;
}
String codeFragment = codeFragments[i];
result.PreviousValue = result.Value;
if (codeFragment.Contains("]"))
{
ProcessArray(result, codeFragment, createIfNotExists);
}
else if (codeFragment.Contains(")"))
{
ProcessMethod(result, codeFragment);
}
else
{
// For set properties we do not need the last value
bool retrieveValue = getLastValue;
if (!retrieveValue)
{
// If this is not the last one in the array, get it anyway
retrieveValue = i + 1 != codeFragments.Length;
}
ProcessProperty(result, codeFragment, retrieveValue);
}
}
}
catch (InvalidCodeFragmentException ex)
{
PentaLogger.LogVerbose("Invalid Property: '" + codeToExecute + "' Invalid Fragment: '" + ex.Message + "'");
}
return result;
}
private static String[] SplitCodeArray(String codeToExecute)
{
List<String> items = new List<String>();
Int32 parenAndbracketCount = 0;
String buffer = "";
foreach (Char c in codeToExecute.ToCharArray())
{
if (c == '.')
{
if (buffer.Length > 0)
{
items.Add(buffer);
buffer = "";
}
continue;
}
else if (c == '[')
{
parenAndbracketCount++;
if (buffer.Length > 0)
{
items.Add(buffer);
}
buffer = c.ToString();
}
else if (c == ']' || c == ')')
{
parenAndbracketCount--;
buffer += c;
if (buffer.Length > 0)
{
items.Add(buffer);
buffer = "";
}
}
else if (Char.IsWhiteSpace(c) || Char.IsControl(c))
{
if (parenAndbracketCount == 0)
{
// Skip it
continue;
}
else
{
buffer += c;
}
}
else if (c == '(')
{
parenAndbracketCount++;
buffer += c;
}
else
{
buffer += c;
}
}
if (buffer.Length > 0)
{
items.Add(buffer);
}
return items.ToArray();
}
private static object[] GetParameters(String codeFragment, MemberInfo memberInfo)
{
String parameters = SplitParametersFromMethod(codeFragment);
if (String.IsNullOrEmpty(parameters))
return new object[0];
object[] parameterArray = parameters.Split(',');
return GetParameters(memberInfo, parameterArray);
}
private static object[] GetParameters(MemberInfo memberInfo, object[] parameterArray)
{
ParameterInfo[] parameterInfo = null;
TypeConverter typeConverter = null;
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if (propertyInfo != null)
{
parameterInfo = propertyInfo.GetIndexParameters();
typeConverter = GetTypeConverter(parameterInfo[0]);
}
else
{
MethodInfo methodInfo = memberInfo as MethodInfo;
if (methodInfo != null)
{
parameterInfo = methodInfo.GetParameters();
}
}
if (parameterInfo == null)
{
return null;
}
object[] returnParameters = new object[parameterInfo.Length];
for (Int32 i = 0; i < parameterArray.Length; i++)
{
ConversionResult converstionResult = ConvertValue(parameterArray[i], parameterInfo[i].ParameterType, typeConverter);
if (converstionResult.Success)
{
returnParameters[i] = converstionResult.ConvertedValue;
}
else
{
return null;
}
}
return returnParameters;
}
private static TypeConverter GetTypeConverter(MemberInfo memberInfo, Type targetType)
{
object[] typeConverters = memberInfo.GetCustomAttributes(typeof(TypeConverterAttribute), true);
if (typeConverters.Length > 0)
{
TypeConverterAttribute typeConverterAttribute = (TypeConverterAttribute)typeConverters[0];
Type typeFromName = Type.GetType(typeConverterAttribute.ConverterTypeName);
if ((typeFromName != null) && typeof(TypeConverter).IsAssignableFrom(typeFromName))
{
return (TypeConverter)Activator.CreateInstance(typeFromName);
}
}
return TypeDescriptor.GetConverter(targetType);
}
private static TypeConverter GetTypeConverter(PropertyInfo propertyInfo)
{
return GetTypeConverter(propertyInfo, propertyInfo.PropertyType);
}
private static TypeConverter GetTypeConverter(FieldInfo fieldInfo)
{
return GetTypeConverter(fieldInfo, fieldInfo.FieldType);
}
private static TypeConverter GetTypeConverter(ParameterInfo parameterInfo)
{
return GetTypeConverter(parameterInfo.Member, parameterInfo.ParameterType);
}
private static ArrayDefinition GetArrayDefinition(object value, String codeToExecute)
{
// All IList classes have an Item property except for System.Array.
List<MemberInfo> retrieveMemberInfos = new List<MemberInfo>();
foreach (PropertyInfo propertyInfo in value.GetType().GetProperties(DefaultBindings))
{
if (propertyInfo.Name == "Item")
{
retrieveMemberInfos.Add(propertyInfo);
}
}
if (retrieveMemberInfos.Count == 0)
{
// We didn't find any Item properties so this is probably an Array. Use the GetValue method
foreach (MethodInfo methodInfo in value.GetType().GetMethods(DefaultBindings))
{
if (methodInfo.Name == "GetValue")
{
retrieveMemberInfos.Add(methodInfo);
}
}
}
// Some members have overloaded this[] methods. Find the correct method.
foreach (MemberInfo memberInfo in retrieveMemberInfos)
{
object[] parameters = GetParameters(codeToExecute, memberInfo);
if (parameters != null)
{
ArrayDefinition arrayDefinition = new ArrayDefinition();
arrayDefinition.Parameters = parameters;
arrayDefinition.RetrieveMemberInfo = memberInfo;
return arrayDefinition;
}
}
return null;
}
private static void ProcessArray(ReflectorResult result, String codeFragment, Boolean createIfNotExists)
{
Int32 failCount = 0;
ArrayDefinition arrayDefinition = GetArrayDefinition(result.Value, codeFragment);
if (arrayDefinition != null)
{
// If this is anything but System.Array we need to call a Property
PropertyInfo propertyInfo = arrayDefinition.RetrieveMemberInfo as PropertyInfo;
if (propertyInfo != null)
{
SetPropertyInfoValue:
try
{
object value = propertyInfo.GetValue(result.Value, arrayDefinition.Parameters);
result.SetResult(value, propertyInfo, arrayDefinition.Parameters);
}
catch (TargetInvocationException ex)
{
failCount++;
if (ex.InnerException is ArgumentOutOfRangeException && failCount == 1 && createIfNotExists)
{
if (CreateArrayItem(result, arrayDefinition))
{
goto SetPropertyInfoValue;
}
}
// Tried to fix it but failed. Blow up
result.Clear();
throw new InvalidCodeFragmentException(codeFragment);
}
}
else
{
// System.Array has a Method to call
MethodInfo methodInfo = arrayDefinition.RetrieveMemberInfo as MethodInfo;
if (methodInfo != null)
{
try
{
// We can't support dynamically creating array items
object value = methodInfo.Invoke(result.Value, arrayDefinition.Parameters);
result.SetResult(value, methodInfo, arrayDefinition.Parameters);
}
catch (TargetInvocationException)
{
result.Clear();
throw new InvalidCodeFragmentException(codeFragment);
}
}
}
}
else
{
result.Clear();
throw new InvalidCodeFragmentException(codeFragment);
}
}
private static Boolean CreateArrayItem(ReflectorResult result, ArrayDefinition arrayDefinition)
{
Type resultType = result.Value.GetType();
Type containedType = null;
if (resultType.IsArray)
{
containedType = resultType.GetElementType();
}
else
{
containedType = resultType.GetGenericArguments()[0];
}
object newInstance = Activator.CreateInstance(containedType);
if (!resultType.IsArray)
{
MethodInfo[] methods = GetMethods(result.Value, "Insert");
foreach (MethodInfo methodInfo in methods)
{
object[] temp = new object[arrayDefinition.Parameters.Length + 1];
arrayDefinition.Parameters.CopyTo(temp, 0);
temp[arrayDefinition.Parameters.Length] = newInstance;
object[] parameters = GetParameters(methodInfo, temp);
if (parameters != null)
{
methodInfo.Invoke(result.Value, parameters);
return true;
}
}
}
return false;
}
private static void ProcessProperty(ReflectorResult result, String codeFragment, bool retrieveValue)
{
// This is just a regular property
PropertyInfo propertyInfo = result.Value.GetType().GetProperty(codeFragment, DefaultBindings);
if (propertyInfo != null)
{
object value = result.Value;
if (retrieveValue)
{
value = propertyInfo.GetValue(result.Value, null);
result.SetResult(value, propertyInfo, null);
}
result.SetResult(value, propertyInfo, null);
}
else
{
// Maybe it is a field
FieldInfo fieldInfo = result.Value.GetType().GetField(codeFragment, DefaultBindings);
if (fieldInfo != null)
{
object value = result.Value;
if (retrieveValue)
{
value = fieldInfo.GetValue(result.Value);
}
result.SetResult(value, fieldInfo, null);
}
else
{
// This item is missing, log it and set the value to null
result.Clear();
throw new InvalidCodeFragmentException(codeFragment);
}
}
}
private static void ProcessMethod(ReflectorResult result, String codeFragment)
{
// This is just a regular property
String methodName = codeFragment.Substring(0, codeFragment.IndexOf('('));
MethodInfo[] methodInfos = GetMethods(result.Value, methodName);
foreach (MethodInfo methodInfo in methodInfos)
{
object[] parameters = GetParameters(codeFragment, methodInfo);
if (parameters != null)
{
object value = methodInfo.Invoke(result.Value, parameters);
result.SetResult(value, null, null);
break;
}
}
}
private static String SplitParametersFromMethod(String codeFragment)
{
char startCharacter = '[';
char endCharacter = ']';
if (codeFragment.EndsWith(")", StringComparison.CurrentCulture))
{
// This is a function
startCharacter = '(';
endCharacter = ')';
}
Int32 startParam = codeFragment.IndexOf(startCharacter) + 1;
if (startParam < 1)
return null;
Int32 endParam = codeFragment.IndexOf(endCharacter);
if (endParam < 0)
return null;
return codeFragment.Substring(startParam, endParam - startParam).Trim();
}
private static MethodInfo[] GetMethods(object value, String methodName)
{
if (String.IsNullOrEmpty(methodName))
{
throw new ArgumentNullException("methodName");
}
if (value == null)
{
return new MethodInfo[0];
}
List<MethodInfo> methodInfos = new List<MethodInfo>();
foreach (MethodInfo methodInfo in value.GetType().GetMethods(DefaultBindings))
{
if (methodInfo.Name == methodName)
{
methodInfos.Add(methodInfo);
}
}
return methodInfos.ToArray();
}
#endregion
#region Helper Classes
private class ArrayDefinition
{
public MemberInfo RetrieveMemberInfo { get; set; }
public object[] Parameters { get; set; }
}
private class ReflectorResult
{
public ReflectorResult(object startValue)
{
SetResult(startValue, null, null);
}
public MemberInfo MemberInfo { get; private set; }
public object[] MemberInfoParameters { get; private set; }
public object PreviousValue { get; set; }
public object Value { get; private set; }
public void SetResult(object value, MemberInfo memberInfo, object[] memberInfoParameters)
{
Value = value;
MemberInfo = memberInfo;
MemberInfoParameters = memberInfoParameters;
}
public void Clear()
{
MemberInfo = null;
Value = null;
PreviousValue = null;
}
}
[Serializable]
[SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
[SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")]
private class InvalidCodeFragmentException : Exception
{
public InvalidCodeFragmentException(String invalidFragment)
: base(invalidFragment)
{
}
}
#endregion
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Diagnostics.CodeAnalysis;
利用制度全球化;
运用系统反思;
名称空间YourNamespace
{
公共结构转换结果
{
公众的成功;
公共对象转换值;
}
公共静态类反射器
{
private static BindingFlags DefaultBindings=BindingFlags.Public | BindingFlags.static | BindingFlags.Instance | BindingFlags.NonPublic;
#区域公共方法
///
///在“源”对象上执行“codeToExecute”字符串
///
///对象,该对象应针对其执行代码
///应执行的代码,例如“Person.Age”
///在源上执行codeToExecute的结果
公共静态对象GetValue(对象源,字符串codeToExecute)
{
ReflectorResult ReflectorResult=GetReflectorResult(源、代码执行、真、假);
if(反射器结果!=null)
{
返回reflectorResult.Value;
}
返回null;
}
///
///将“源”对象设置为“codeToExecute”中指定的“值”
///
///对象,该对象应针对其执行代码
///应执行的代码,例如“Person.Age”
///值将源代码+代码执行设置为。
公共静态布尔设置值(对象源、字符串代码执行、对象值)
{
返回设置值(source,codeToExecute,value,false);
}
///
///将“源”对象设置为“codeToExecute”中指定的“值”
///
///对象,该对象应针对其执行代码
///应执行的代码,例如“Person.Age”
///值将源代码+代码执行设置为。
///创建它找不到的项
公共静态布尔SetValue(对象源、字符串codeToExecute、对象值、布尔createIfNotExists)
{
布尔值=真;
ReflectorResult ReflectorResult=GetReflectorResult(源、codeToExecute、false、createIfNotExists);
if(反射器结果!=null)
{
TypeConverter-TypeConverter=null;
PropertyInfo PropertyInfo=reflector result.MemberInfo作为PropertyInfo;
if(propertyInfo!=null)
{
if(propertyInfo.CanWrite)
{
typeConverter=GetTypeConverter(propertyInfo);
ConversionResult ConversionResult=ConvertValue(值,propertyInfo.PropertyType,typeConverter);
if(conversionResult.Success)
{
propertyInfo.SetValue(reflectorResult.PreviousValue、conversionResult.ConvertedValue、reflectorResult.MemberInfoParameters);
}
其他的
{
已执行=错误;
LogVerbose(“无效值:”+值);
}
}
}
其他的
{
FieldInfo FieldInfo=Reflector Result.MemberInfo作为FieldInfo;
如果(fieldInfo!=null)
{
typeConverter=GetTypeConverter(fieldInfo);
ConversionResult ConversionResult=ConvertValue(值,fieldInfo.FieldType,typeConverter);
if(conversionResult.Success)
{
fieldInfo.SetValue(reflectorResult.PreviousValue、conversionResult.ConvertedValue);
}
其他的
{
已执行=错误;
LogVerbose(“无效值:”+值);
}
}
其他的
{
//属性和字段都无效
已执行=错误;
}
}
}
其他的
{
已执行=错误;
}
已执行的返回;
}
///
///将“源”对象设置为“codeToExecute”中指定的“值”
///
///对象,该对象应针对其执行代码
///应该