需要帮助纠正反思

时间:2014-08-29 07:47:55

标签: c# generics reflection

以下程序仅适用于位于主项目中的类。您是否愿意建议或更正代码,以便可以使用其他项目中的类。我将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
}

非常感谢提前!!!

1 个答案:

答案 0 :(得分:1)

你的问题就在这一行:

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

您需要枚举所有引用的程序集,而不仅仅是当前正在执行的程序集,因此可能需要在GetReferencedAssemblies()的结果上使用GetExecutingAssembly(),因为您的主项目是执行程序集和您引用的项目将是一个引用的集合。