2014-08-29 72 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