C# 尝试使用动态类型时出现RuntimeBinderException
我试图在我的当前日志模式中实现log4net,我已经设置好了,但是在尝试将我的enum LogLevel转换为log4net的Level类时遇到了一些问题 问题在于将loglevel更改为方法: 例外情况: 类型的例外 中出现“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException” System.Core.dll,但未在用户代码中处理 其他信息:System.Reflection.TypeInfo不包含 信息的任何定义 我是否认为这是错误的,或者我可以这样解决它:C# 尝试使用动态类型时出现RuntimeBinderException,c#,dynamic,log4net,C#,Dynamic,Log4net,我试图在我的当前日志模式中实现log4net,我已经设置好了,但是在尝试将我的enum LogLevel转换为log4net的Level类时遇到了一些问题 问题在于将loglevel更改为方法: 例外情况: 类型的例外 中出现“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException” System.Core.dll,但未在用户代码中处理 其他信息:System.Reflection.TypeInfo不包含 信息的任何定义 我是否认为这是错误的,
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;
}
公共类Log4NetTargets:ILogTarget
{
公共无效日志(日志级别、日志级别、字符串关联ID、类型、字符串成员、字符串消息、IDictionary customData)
{
var log=log4net.LogManager.GetLogger(类型);
var级别=变更LogLevelTo(logLevel);
log.Logger.log(类型、级别、字符串.Format(“ID:{0}消息:{1}自定义数据:{2}”、correlationId、消息、自定义数据)、新异常();
}
公共无效日志(日志级别、日志级别、字符串关联ID、类型、字符串成员、异常、IDictionary customData)
{
var log=log4net.LogManager.GetLogger(类型);
var级别=变更LogLevelTo(logLevel);
log.Logger.log(类型、级别、字符串.Format(“ID:{0}异常:{1}自定义数据:{2}”、correlationId、异常、自定义数据)、新异常();
}
私有T ChangeLogLevelTo(LogLevel LogLevel)
{
var结果=默认值(T);
动态类型=类型(T);
开关(日志级别)
{
案例日志级别。错误:
结果=dynamicType.Error;
打破
案例日志级别。信息:
结果=dynamicType.Info;
打破
案例日志级别。跟踪:
结果=dynamicType.Trace;
打破
案例日志级别。警告:
结果=dynamicType.Warn;
打破
}
返回结果;
}
假设各种级别
类型都是指定类型上的公共静态属性或字段,实现这一点的最简单方法是使用反射:
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);
}
}
公共静态类类型扩展
{
公共静态T GetStaticPropertyValueOfType(此类型,字符串名称)
{
var property=type.GetProperty(名称,BindingFlags.Public | BindingFlags.Static);
if(属性!=null
&&property.GetIndexParameters().Length==0
&&typeof(T).IsAssignableFrom(property.PropertyType)
&&property.getMethod(true)!=null)
{
return(T)property.getMethod(true).Invoke(null,新对象[0]);
}
var field=type.GetField(名称,BindingFlags.Public | BindingFlags.Static);
如果(字段!=null
&&typeof(T).IsAssignableFrom(field.FieldType))
返回(T)字段。GetValue(null);
返回默认值(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;
}
private T ChangeLogLevelTo(LogLevel LogLevel)
{
var结果=默认值(T);
开关(日志级别)
{
案例日志级别。错误:
结果=类型(T).GetStaticPropertyValueOfType(“错误”);
打破
案例日志级别。信息:
结果=类型(T).GetStaticPropertyValueOfType(“信息”);
打破
案例日志级别。跟踪:
结果=类型(T).GetStaticPropertyValueOfType(“跟踪”);
打破
案例日志级别。警告:
结果=类型(T).GetStaticPropertyValueOfType(“警告”);
打破
}
返回结果;
}
1)为什么ChangeLogLevelTo
需要通用?2)dynamicdynamictype=typeof(T);
不起作用,因为它没有名为Info
等的属性。实际上,它不需要是泛型的。我正试图使它泛型化,这样我就不需要使用两个或更多看起来几乎相同的switch语句。将来我想再实现一个日志框架,然后我需要再次这样做。谢谢!现在我如果干燥比速度更重要,则需要设计:)