2012-05-23 2 views
2

Хорошо, это меня озадачивает. У меня есть абстрактный базовый класс Testbase и он имеет абстрактную функцию под названием RunTest. В папке у меня есть набор классов, которые наследуют этот абстрактный класс. В тестовом контроллере я вызываю следующий код, чтобы создать список экземпляров этих тестовых классов.Использование выражения Lambda вызывает изменение типа класса

 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); 
     } 

в одном из классов RunTest функции я очистки кода и решил использовать лямбда-выражения и пробовал различные версии.

pullservice = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName == serviceName); 

и

pullservice = ServiceController.GetServices().Where(s => s.DisplayName.Equals("Pull Service")).ToList()[0]; 

являются те, которые я помню, но в любое время я использую лямбда, а не проходит через какой-то запутанные петли Еогеасп я получаю 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() 
+1

BTW, 'объект T' должен быть' Тип T'; это позволит избежать внутреннего броска. – SLaks

+0

изменил спасибо :-) – MajinFro

ответ

2

Выражение lambda генерирует класс анонимного закрытия для хранения локальных переменных.
Ваш код неправильно подбирает этот класс.

Вы должны добавить

where typeof(TestBase).IsAssignableFrom(t) 
+0

Спасибо, что отлично поработал. – MajinFro

1

Вы должны проверить, если тип фактически расширяет Testbase:

var testList = (from t in Assembly.GetExecutingAssembly().GetTypes() 
       where t.Namespace == ns && typeof(TestBase).IsAssignableFrom(t) 
       select (TestBase)Activator.CreateInstance(t) 
       ).ToList(); 
+0

по какой-то причине при попытке найти это не найдет ни одного из классов, но просто добавить && typeof в исходный запрос, казалось, исправить проблему – MajinFro