缺少类型的构造方法 - 使用泛型方法添加到通用数组

时间:2014-11-11 07:47:01

标签: c# arrays generics types casting

我试图创建一个泛型类数组,如下所示,但是,我遇到了麻烦。第一个问题是错误" MissingMethodException:找不到类型为Dog的构造函数"调用AddGenericComponent方法时。这个方法应该向组件数组中添加抛入其中的任何类,并且还返回刚刚添加的组件,其修改方式类似于" Test()"。有没有人有关于如何做到这一点的建议或解决方案?

public void Test()
{
    MyClass myClass = new MyClass();
    Dog dog = myClass.AddGenericComponent<Dog>();
    dog.name = "Fluffy";
    Console.Writeline(dog.name);
    //testing the accessor
    dog = myClass.GetGenericComponent<Dog>();
    dog.name = "Fluffy mod";
    Console.Writeline(dog.name);
}


public class MyClass
{
   //must be an array, not list
   GenericComponent<Object>[] components = new GenericComponent<Object>[1];
   public T AddGenericComponent<T>()
   {
       GenericComponent<Object>[] newArray = new GenericComponent<Object>[components.Length + 1];
       components.CopyTo(newArray, 0);
       components = newArray;
       components[components.Length - 1] = new GenericComponent<Object>();
       return (T)Activator.CreateInstance(typeof(T), new GenericComponent<Object> { });
   }
   public T GetGenericComponent<T>()
   {
      return (T)Array.Find(components, c => c.GetType() == typeof(T)).component;
   }
}

public class GenericComponent<T> where T: new()
{
   public T component;
   public GenericComponent()
   {
       component = new T();
   }
}

public class Dog
{
   public string name = "";
   public Dog(){}
   public Dog(string name)
   {
      this.name = name;
   }

}

编辑:

我想我已经解决了。

 public T AddGenericComponent<T>()
 {
    GenericComponent<Object>[] newArray = new GenericComponent<Object>[components.Length + 1];
    components.CopyTo(newArray, 0);
    components = newArray;
    GenericComponent<Object> newComponent = new GenericComponent<Object>();//;(T)Activator.CreateInstance(typeof(T));
    newComponent.component = (T)Activator.CreateInstance(typeof(T));
    components[components.Length - 1] = newComponent;
    return (T)Activator.CreateInstance(typeof(T));
 }

2 个答案:

答案 0 :(得分:0)

我真的不明白你在这里做了什么,但是:

public static object CreateInstance(Type type, params object[] args);

args是ctor params。

Activator.CreateInstance(typeof(Dog)); - &gt;这将调用public Dog(){} ctor。

Activator.CreateInstance(typeof(Dog),"myString"); - &gt;这将调用public Dog(string name){} ctor。

Activator.CreateInstance(typeof(T), new GenericComponent<Object> { }); - &gt;这将调用不存在public Dog(GenericComponent<Object> param){} ctor,因此您获得例外

修改: 我试着理解你为什么做了你做过但却做不到的事。无论如何,看起来你想要这样的东西:

    public void Test()
    {
        MyClass myClass = new MyClass();
        Dog dog = myClass.AddGenericComponent<Dog>();
        dog.name = "Fluffy";
        MessageBox.Show(dog.name);
        //testing the accessor - ADD a NULL CHECK!!!
        dog = myClass.GetGenericComponent<Dog>();
        dog.name = "Fluffy mod";
        MessageBox.Show(dog.name);
    }

    public class MyClass
    {
        List<Object> objects = new List<Object>();

        public T AddGenericComponent<T>() where T : class, new()
        {
            T obj = GetGenericComponent<T>();

            if (obj == null)
            {
                obj = new T();
                objects.Add(obj);
            }

            return obj;
        }

        public T GetGenericComponent<T>() where T : class, new()
        {
            var relevantObj = objects.FirstOrDefault(o => o.GetType() == typeof(T));
            if (relevantObj != null)
            {
                return relevantObj as T;
            }

            return null;
        }
    }

    public class Dog
    {
        public string name = "";
        public Dog() { }
        public Dog(string name)
        {
            this.name = name;
        }

    }

答案 1 :(得分:0)

我使用了以下内容:

class Test
{
    public void TestStart()
    {
        MyClass myClass = new MyClass();
        Dog dog = myClass.AddGenericComponent<Dog>();
        dog.name = "Fluffy";
        Console.Writeline(dog.name);
        //testing the accessor
        dog = myClass.GetGenericComponent<Dog>();
        dog.name = "Fluffy mod";
        Console.Writeline(dog.name);
    }
}
[Serializable]
public class GameObject
{
    List<GenericComponent<Object>> componentList = new List<GenericComponent<Object>>();

    //returns first found in list.
    public T GetComponent<T>()
    {
        return (T)componentList.Find(c => c.component.GetType() == typeof(T)).component;
    }
    //add a component to component list.
    public T AddComponent<T>()
    {
        GenericComponent<Object> newComponent = new GenericComponent<Object>();
        newComponent.component = (T)Activator.CreateInstance(typeof(T));
        componentList.Add(newComponent);
        return (T)newComponent.component;
    }
    //returns all components of type T
    public List<T> GetComponents<T>()
    {
        List<T> r = new List<T>();
        for (int i = 0; i < componentList.Count; i++)
        {
            if (componentList[i].component.GetType() == typeof(T))
            {
                r.Add((T)componentList[i].component);
            }
        }
        return r;
    }
}
[Serializable]
public class GenericComponent<T> where T : new()
{
    public T component;
    public GenericComponent()
    {
        component = new T();
    }
}
[Serializable]
public class Dog
{
    public string name = "";
    public Dog() { }
    public Dog(string name)
    {
        this.name = name;
    }
}