C# 将泛型类型的实例作为泛型类的动态实例上的参数传递
我试图构建一个动态类型列表,它实际上是C# 将泛型类型的实例作为泛型类的动态实例上的参数传递,c#,generics,dynamic,exception-handling,C#,Generics,Dynamic,Exception Handling,我试图构建一个动态类型列表,它实际上是ExceptionLogCondition类型,它是一个定义需要排除的异常类型和特定异常类型的可选条件谓词的类 问题在于将异常传递给IsConditionValid(te)方法。我总是遇到这样的例外: 匹配的最佳重载方法 'MVCAPApplication.ErrorLogCondition.IsConditionValid(Exceptions.AjaxOnlyViolationException)' 有一些无效的参数 堆栈跟踪: 目标(闭包、调用站点、对
ExceptionLogCondition
类型,它是一个定义需要排除的异常类型和特定异常类型的可选条件谓词的类
问题在于将异常传递给IsConditionValid(te)
方法。我总是遇到这样的例外:
匹配的最佳重载方法
'MVCAPApplication.ErrorLogCondition.IsConditionValid(Exceptions.AjaxOnlyViolationException)'
有一些无效的参数
堆栈跟踪:
目标(闭包、调用站点、对象、异常)位于
System.Dynamic.UpdateLegates.UpdateAndExecute2[T0,T1,TRet](调用站点
站点,T0 arg0,T1 arg1)位于
CONCENTRA.MOS.mvcapapplication.ErrorLog_筛选(对象发送方,
C中的ExceptionFilterEventArgs(e):\u teamprojects\Main\Source\Global.asax.cs:line
213在Elmah.ErrorLogModule.OnFiltering(例外的FilterEventArgs
args)位于Elmah.ErrorLogModule.LogException(异常e,HttpContext
上下文)位于Elmah.ErrorLogModule.OnError(对象发送方,EventArgs
args)位于System.EventHandler.Invoke(对象发送方,EventArgs e)位于System.Web.HttpApplication.RaiseOnError()处 代码如下:
public class MvcApplication : System.Web.HttpApplication
{
protected void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
{
var exceptionsToDismiss = new List<dynamic>() {
new ErrorLogCondition<Exceptions.AjaxOnlyViolationException>(),
new ErrorLogCondition<WebsiteException>(c => c.LogError == true)
};
foreach (var exd in exceptionsToDismiss)
{
if(((Type)exd.ExceptionType).Equals(e.Exception.GetBaseException().GetType()) &&
exd.IsConditionValid(e.Exception.GetBaseException()))
// The second condition fails even though the type is correct (see first if condition).
e.Dismiss();
}
}
}
public class ErrorLogCondition<T> where T : Exception, new() {
public Type ExceptionType {get;set;}
public Predicate<T> ExceptionTypeCondition { get; set; }
public ErrorLogCondition() {
ExceptionType = typeof(T);
}
public ErrorLogCondition(Predicate<T> c)
{
ExceptionType = typeof(T);
ExceptionTypeCondition = c;
}
public bool IsConditionValid(T e)
{
return ExceptionTypeCondition == null || ExceptionTypeCondition.Invoke(e);
}
}
公共类MVCAPApplication:System.Web.HttpApplication
{
受保护的无效错误日志\u筛选(对象发送方,ExceptionFilterEventArgs e)
{
var exceptionsToDismiss=新列表(){
新的ErrorLogCondition(),
新的ErrorLogCondition(c=>c.LogError==true)
};
foreach(异常ToDismiss中的var exd)
{
if(((Type)exd.ExceptionType).Equals(e.Exception.GetBaseException().GetType())&&
exd.IsConditionValid(e.Exception.GetBaseException())
//即使类型正确,第二个条件也会失败(请参阅第一个if条件)。
e、 解雇();
}
}
}
公共类ErrorLogCondition,其中T:Exception,new(){
公共类型异常类型{get;set;}
公共谓词ExceptionTypeCondition{get;set;}
公共ErrorLogCondition(){
例外类型=类型(T);
}
公共ErrorLogCondition(谓词c)
{
例外类型=类型(T);
ExceptionTypeCondition=c;
}
公共边界条件有效(T e)
{
返回ExceptionTypeCondition==null | | ExceptionTypeCondition.Invoke(e);
}
}
我的直觉告诉我可能做得有点过头了。因此,我愿意接受其他建议。尽管如此,我还是想知道为什么这不起作用。从提供的代码中我扣除e.Exception.GetBaseException()
返回一个类型的实例,该实例不可强制转换为AjaxOnlyViolationException
类型。从提供的代码中我扣除e.Exception.GetBaseException())
返回类型的实例,该实例不可强制转换为AjaxOnlyViolationException
类型。GetBaseException()
返回一个异常
,该异常不是IsConditionValid
可以接受的。你在道德上等同于这一准则:
Exception baseExp = e.Exception.GetBaseException() //which is a AjaxOnlyViolation
IsConditionValid( baseExp);
//where isconditionvalid is:
bool IsConditionValid(AjaxOnlyViolation e) { }
运行时的实例是否是运行时的AjaxOnlyViolation并不重要——编译器不知道这一点。重要的是,它被尽可能地声明为任何异常,并且没有从exception
到AjaxOnlyViolation
的隐式转换。因此,错误
你需要告诉编译器;您可以更改IsConditionValid以接受异常,然后将其强制转换为该方法中的T
,或者在调用该方法之前强制转换它。GetBaseException()
返回一个异常
,这不是IsConditionValid
可以接受的。你在道德上等同于这一准则:
Exception baseExp = e.Exception.GetBaseException() //which is a AjaxOnlyViolation
IsConditionValid( baseExp);
//where isconditionvalid is:
bool IsConditionValid(AjaxOnlyViolation e) { }
运行时的实例是否是运行时的AjaxOnlyViolation并不重要——编译器不知道这一点。重要的是,它被尽可能地声明为任何异常,并且没有从exception
到AjaxOnlyViolation
的隐式转换。因此,错误
你需要告诉编译器;您可以更改IsConditionValid以接受异常,然后将其强制转换为该方法中的T
,或者在调用该方法之前强制转换它。因为GetBaseException()
返回类型为Exception
,无法找到任何方法公共bool IsConditionValid(异常e)
。您应该在签名中提供一个带有异常
类型的方法
然而,对于性能问题,这可能不是更好的方法(请参阅MSDN关于动力学)
但是您可以使用一个列表
,它可以在减少所需代码行的同时完成相同的工作,IMHO。因为GetBaseException()
返回类型是Exception
,找不到任何方法公共bool IsConditionValid(Exception e)
。您应该在签名中提供一个带有异常
类型的方法
然而,对于性能问题,这可能不是更好的方法(请参阅MSDN关于动力学)
但是你可以使用一个
列表
,它可以做同样的工作,同时减少所需的代码行,IMHO。如果这是真的,第一个条件将失败,第二个条件将永远不会执行。@Peter:是的,但是你的methid需要AjaxOnlyViolationException,但是你向它传递一个基类型。您不能执行上转换。如果这是真的,第一个条件将失败,第二个条件将永远不会执行。@Peter:是的,但您的methid需要AjaxOnlyViolationException,但您向它传递了一个基类型。您不能执行上转换。您可能应该为ErrorLogCondition
private:public Type Exception的ExceptionType
属性设置setter