尝试使用动态类型时出现 RuntimeBinderException
RuntimeBinderException when trying to use dynamic type
我正在尝试在我已设置的当前日志模式中实施 log4net,但在尝试将我的枚举 LogLevel 转换为 log4net 级别 class 时我 运行 遇到了一些问题 class。
问题在于 ChangeLogLevelTo 方法:
异常:
An exception of type
'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in
System.Core.dll but was not handled in user code
Additional information: System.Reflection.TypeInfo does not contain
any definition for info.
我是不是想错了,或者我可以这样解决:
public class Log4NetTargets : ILogTarget
{
public void Log(LogLevel logLevel, string correlationId, Type type, string member, string message, IDictionary<string, string> customData)
{
var log = log4net.LogManager.GetLogger(type);
var level = ChangeLogLevelTo<Level>(logLevel);
log.Logger.Log(type, level, string.Format("ID: {0} MESSAGE: {1} CUSTOM DATA: {2}", correlationId, message, customData ), new Exception());
}
public void Log(LogLevel logLevel, string correlationId, Type type, string member, Exception exception, IDictionary<string, string> customData)
{
var log = log4net.LogManager.GetLogger(type);
var level = ChangeLogLevelTo<Level>(logLevel);
log.Logger.Log(type, level, string.Format("ID: {0} EXCEPTION: {1} CUSTOM DATA: {2}", correlationId, exception, customData), new Exception());
}
private T ChangeLogLevelTo<T>(LogLevel logLevel)
{
var result = default(T);
dynamic dynamicType = typeof(T);
switch (logLevel)
{
case LogLevel.Error:
result = dynamicType.Error;
break;
case LogLevel.Info:
result = dynamicType.Info;
break;
case LogLevel.Trace:
result = dynamicType.Trace;
break;
case LogLevel.Warning:
result = dynamicType.Warn;
break;
}
return result;
}
假设各种Level
类型都是public指定类型的静态属性或字段,最简单的方法是用反射:
public static class TypeExtensions
{
public static T GetStaticPropertyValueOfType<T>(this Type type, string name)
{
var property = type.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
if (property != null
&& property.GetIndexParameters().Length == 0
&& typeof(T).IsAssignableFrom(property.PropertyType)
&& property.GetGetMethod(true) != null)
{
return (T)property.GetGetMethod(true).Invoke(null, new object [0]);
}
var field = type.GetField(name, BindingFlags.Public | BindingFlags.Static);
if (field != null
&& typeof(T).IsAssignableFrom(field.FieldType))
return (T) field.GetValue(null);
return default(T);
}
}
然后像这样称呼它
private T ChangeLogLevelTo<T>(LogLevel logLevel)
{
var result = default(T);
switch (logLevel)
{
case LogLevel.Error:
result = typeof(T).GetStaticPropertyValueOfType<T>("Error");
break;
case LogLevel.Info:
result = typeof(T).GetStaticPropertyValueOfType<T>("Info");
break;
case LogLevel.Trace:
result = typeof(T).GetStaticPropertyValueOfType<T>("Trace");
break;
case LogLevel.Warning:
result = typeof(T).GetStaticPropertyValueOfType<T>("Warn");
break;
}
return result;
}
我正在尝试在我已设置的当前日志模式中实施 log4net,但在尝试将我的枚举 LogLevel 转换为 log4net 级别 class 时我 运行 遇到了一些问题 class。
问题在于 ChangeLogLevelTo 方法:
异常:
An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code
Additional information: System.Reflection.TypeInfo does not contain any definition for info.
我是不是想错了,或者我可以这样解决:
public class Log4NetTargets : ILogTarget
{
public void Log(LogLevel logLevel, string correlationId, Type type, string member, string message, IDictionary<string, string> customData)
{
var log = log4net.LogManager.GetLogger(type);
var level = ChangeLogLevelTo<Level>(logLevel);
log.Logger.Log(type, level, string.Format("ID: {0} MESSAGE: {1} CUSTOM DATA: {2}", correlationId, message, customData ), new Exception());
}
public void Log(LogLevel logLevel, string correlationId, Type type, string member, Exception exception, IDictionary<string, string> customData)
{
var log = log4net.LogManager.GetLogger(type);
var level = ChangeLogLevelTo<Level>(logLevel);
log.Logger.Log(type, level, string.Format("ID: {0} EXCEPTION: {1} CUSTOM DATA: {2}", correlationId, exception, customData), new Exception());
}
private T ChangeLogLevelTo<T>(LogLevel logLevel)
{
var result = default(T);
dynamic dynamicType = typeof(T);
switch (logLevel)
{
case LogLevel.Error:
result = dynamicType.Error;
break;
case LogLevel.Info:
result = dynamicType.Info;
break;
case LogLevel.Trace:
result = dynamicType.Trace;
break;
case LogLevel.Warning:
result = dynamicType.Warn;
break;
}
return result;
}
假设各种Level
类型都是public指定类型的静态属性或字段,最简单的方法是用反射:
public static class TypeExtensions
{
public static T GetStaticPropertyValueOfType<T>(this Type type, string name)
{
var property = type.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
if (property != null
&& property.GetIndexParameters().Length == 0
&& typeof(T).IsAssignableFrom(property.PropertyType)
&& property.GetGetMethod(true) != null)
{
return (T)property.GetGetMethod(true).Invoke(null, new object [0]);
}
var field = type.GetField(name, BindingFlags.Public | BindingFlags.Static);
if (field != null
&& typeof(T).IsAssignableFrom(field.FieldType))
return (T) field.GetValue(null);
return default(T);
}
}
然后像这样称呼它
private T ChangeLogLevelTo<T>(LogLevel logLevel)
{
var result = default(T);
switch (logLevel)
{
case LogLevel.Error:
result = typeof(T).GetStaticPropertyValueOfType<T>("Error");
break;
case LogLevel.Info:
result = typeof(T).GetStaticPropertyValueOfType<T>("Info");
break;
case LogLevel.Trace:
result = typeof(T).GetStaticPropertyValueOfType<T>("Trace");
break;
case LogLevel.Warning:
result = typeof(T).GetStaticPropertyValueOfType<T>("Warn");
break;
}
return result;
}