2014-08-29 75 views
0

以下程序仅适用于位于主项目中的类。你会如此友善地建议或纠正代码,以便可以使用其他项目中的类。我将ClassLibrary1项目的引用添加到Example01项目。需要帮助纠正反射

The desired project

我正的错误是

Unhandled Exception: System.ArgumentNullException: Value cannot be null. 
Parameter name: type 
    at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
    at System.Activator.CreateInstance(Type type) 
    at Example01.Program.InstantiateObject(String assemblyName, String fullName) in c:\Projects\Example01\Example01\Program.cs:line 59 
    object obj = Activator.CreateInstance(objectToInstantiate); 
    at Example01.Program.RandomizeList[TClass](Int32 count, String assemblyName) in c:\Projects\Example01\Example01\Program.cs:line 34 
    randomizedList.Add(
    at Example01.Program.Main(String[] args) in c:\Projects\Example01\Example01\Program.cs:line 18 
    List<Class02> randomizedList03 = RandomizeList<Class02>(); 

这是我与参考代码什么可行,什么失败:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using ClassLibrary1.Classes; 

namespace Example01 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // This works 
      List<Class01> randomizedList01 = RandomizeList<Class01>(); 
      // This works 
      List<Test01> randomizedList02 = RandomizeList<Test01>(); 
      // This fails 
      List<Class02> randomizedList03 = RandomizeList<Class02>(); 

      Console.ReadKey(); 
     } 


     private static List<TClass> RandomizeList<TClass>(int count = 10, string assemblyName = "") 
     { 
      if (assemblyName.Length == 0) 
       assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; 
      var listOfSubClasses = SubClasses<TClass>(); 
      var randomizedList = new List<TClass>(); 
      var rand = new Random(); 
      count = 10; 

      for (int i = 0; i < count; i++) 
       randomizedList.Add(
        (TClass) 
         InstantiateObject(assemblyName, 
         listOfSubClasses.ElementAt(rand.Next(listOfSubClasses.Count())) 
         .FullName)); 
      return new List<TClass>(randomizedList as IEnumerable<TClass>); 
     } 

     // Enumerate all subclasses for the specified class 
     public static IEnumerable<Type> SubClasses<TClass>() 
     { 
      var subclasses = 
       (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
       from type in assembly.GetTypes() 
       where type.IsSubclassOf(typeof(TClass)) 
       select type).ToList(); 
      return subclasses; 
     } 

     private static object InstantiateObject(string assemblyName, string fullName) 
     { 
      Assembly аsm = Assembly.Load(assemblyName); 
      // Get the assembly metadata 
      Type objectToInstantiate = аsm.GetType(fullName); 
      // Create object on the fly 
      object obj = Activator.CreateInstance(objectToInstantiate); 
      return obj; 
     } 
    } 

    #region Sample Classes 
    public class Class01 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
    } 

    public class SubClass0101 : Class01 
    { 
     public int Length { get; set; } 
    } 

    public class SubClass0102 : Class01 
    { 
     public int Length { get; set; } 
    } 

    public class SubClass0103 : Class01 
    { 
     public int Length { get; set; } 
    } 
    #endregion 
} 

许多在此先感谢!

+0

重构是重塑工作代码。无论如何,最有可能的'objectToInstantiate'是'null'。 – CodeCaster 2014-08-29 07:50:04

+0

你是对的!但是为了解决它该怎么做?谢谢! – Tracey23 2014-08-29 08:09:31

回答

1

你的问题是这样的一行:

assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name 

您需要枚举所有引用的程序,而不只是当前执行的程序集,所以可能需要使用GetReferencedAssemblies()上的GetExecutingAssembly()结果作为你的主要项目是执行程序集并且您引用的项目将成为引用的程序集。

+0

谢谢你的想法!不幸的是,它抱怨错误'无法访问静态上下文中的非静态方法'GetReferencedAssemblies'。 – Tracey23 2014-08-29 08:24:32

+0

啊,我没有看到静态标记 - 请直接使用'GetReferencedAssemblies()'而不是'GetExecutingAssembly()',然后使用每个程序集名称来根据需要提取它们的类。 – toadflakz 2014-08-29 08:36:58

+0

toadflakz,如果我真的与反射斗争,你会如此善待我的代码示例吗?高度欣赏你的友善提前! – Tracey23 2014-08-29 08:51:31