2

Ok this one is puzzling me. I have an abstract base class named Testbase and it has an abstract function called RunTest. In a folder I have a collection of classes that inherit this abstract class. In a test controller I call the following code to create a list of instances of these Test Classes.

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

in one of the classes RunTest function I was cleaning up code and decided to use lambda expressions and tried various versions.

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

and

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

are the ones I remember but anytime i use the lambda's rather than running through some convoluted foreach loop i get an invalidcastexception on the line of code

TestBase test = (TestBase)Activator.CreateInstance(t as Type);

Exception:

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
  • 1
    BTW, object t should be Type t; this will avoid the inner cast. Commented May 23, 2012 at 15:39

2 Answers 2

2

The lambda expression generates an anonymous closure class to hold local variables.
Your code is incorrectly picking up this class.

You should add

where typeof(TestBase).IsAssignableFrom(t)
Sign up to request clarification or add additional context in comments.

Comments

1

You need to check if the Type actually extends Testbase:

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

1 Comment

for some reason when trying out this it would not find any of the classes but just adding the && typeof to the original query seemed to fix the issue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.