C# 使用Lambda表达式会导致类类型的更改
好吧,这个让我很困惑。我有一个名为Testbase的抽象基类,它有一个名为RunTest的抽象函数。在一个文件夹中,我有一组继承这个抽象类的类。在测试控制器中,我调用以下代码来创建这些测试类的实例列表C# 使用Lambda表达式会导致类类型的更改,c#,.net,reflection,lambda,abstract,C#,.net,Reflection,Lambda,Abstract,好吧,这个让我很困惑。我有一个名为Testbase的抽象基类,它有一个名为RunTest的抽象函数。在一个文件夹中,我有一组继承这个抽象类的类。在测试控制器中,我调用以下代码来创建这些测试类的实例列表 String ns = "HCTCommon.Tests"; var query = from t in Assembly.GetExecutingAssembly().GetTypes() where t.Namespace
String ns = "HCTCommon.Tests";
var query = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.Namespace == ns
select t;
foreach (object t in query)
{
TestBase test = (TestBase)Activator.CreateInstance(t as Type);
testList.Add(test);
}
在运行测试函数的一个类中,我正在清理代码,决定使用lambda表达式,并尝试了各种版本
pullservice = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName == serviceName);
及
是我记得的那些,但是每当我使用lambda而不是运行一些复杂的foreach循环时,我在代码行上得到一个invalidcastexception
TestBase test = (TestBase)Activator.CreateInstance(t as Type);
例外情况:
Unable to cast object of type '<>c__DisplayClass4' to type 'HCTCommon.TestBase'.
Stack Trace:
at HCTCommon.TestController.populateTestList()
at HCTCommon.TestController..ctor(RegistryKey Key)
at HealthCheck.HealthCheckForm.InitializeTestPanels() in C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\HCTCommon\HealthCheck\HealthCheckForm.cs:line 55
at HealthCheck.HealthCheckForm..ctor() in C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\HCTCommon\HealthCheck\HealthCheckForm.cs:line 26
at HealthCheck.Program.registrycheck() in C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\HCTCommon\HealthCheck\Program.cs:line 63
at HealthCheck.Program.Main() in C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\HCTCommon\HealthCheck\Program.cs:line 34
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
无法将类型为“c\uu DisplayClass4”的对象强制转换为类型为“HCTCommon.TestBase”。
堆栈跟踪:
在HCTCommon.TestController.populateTestList()中
在HCTCommon.TestController..ctor(注册表键)
在C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\hctccommon\HealthCheck\HealthCheckForm.cs中的HealthCheck.HealthCheckForm.InitializeTestPanels()处:第55行
在C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\HCTCommon\HealthCheck\HealthCheckForm.cs中的HealthCheck.HealthCheckForm..ctor()处:第26行
在C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\hctccommon\HealthCheck\Program.cs中的HealthCheck()处:第63行
在C:\Users\bkoch.ESI911\documents\visual studio 2010\Projects\HCTCommon\HealthCheck\Program.cs中的HealthCheck.Program.Main()处:第34行
位于System.AppDomain.\u nexecutestAssembly(程序集,字符串[]args)
位于System.AppDomain.ExecuteAssembly(字符串汇编文件、证据汇编安全性、字符串[]args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()上
位于System.Threading.ThreadHelper.ThreadStart\u上下文(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
位于System.Threading.ThreadHelper.ThreadStart()处
lambda表达式生成一个匿名闭包类来保存局部变量。您的代码错误地拾取此类 你应该加上
where typeof(TestBase).IsAssignableFrom(t)
您需要检查类型是否实际扩展了
Testbase
:
var testList = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.Namespace == ns && typeof(TestBase).IsAssignableFrom(t)
select (TestBase)Activator.CreateInstance(t)
).ToList();
顺便说一句,
对象t
应该是类型t
;这将避免内部强制转换。出于某种原因,在尝试此操作时,它将找不到任何类,但仅将&&typeof添加到原始查询似乎可以解决此问题
var testList = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.Namespace == ns && typeof(TestBase).IsAssignableFrom(t)
select (TestBase)Activator.CreateInstance(t)
).ToList();