【问题标题】:Method with type parameter to return array of said type带有类型参数的方法返回所述类型的数组
【发布时间】:2011-07-15 02:32:09
【问题描述】:

我正在尝试在 C# 中创建一个通用方法,该方法将返回指定类型的数组。这就是我目前的方法:

private T[] GetKeys<T>(string key, Dictionary<string, object> obj) where T : new()
{
    if (obj.ContainsKey(key))
    {
        object[] objs = (object[])obj[key];
        T[] list = new T[objs.Length];
        for (int i = 0; i < objs.Length; i++)
        {
            list[i] = (T)Activator.CreateInstance(
                             typeof(T),
                             new object[] {
                                 (Dictionary<string, object>)objs[i] 
                             });
        }
        return list;
    }
    else
    {
        return null;
    }
}

由于这个类是在内部使用的,并且不能通过使用库来使用,我已经知道哪些类将被放入&lt;T&gt;。所有类在它们的构造函数中都有相同的参数。但是在这段代码编译之前,我必须给他们一个没有参数的公共构造函数。现在,当我到达Activator.CreateInstance 行时,我收到一条错误消息Constructor on type 'MyNamespace.MyClass+MyOtherClass' not foundMyClass 是包含上述方法的类。 MyOtherClass 是作为T 传入的类。

任何帮助将不胜感激谢谢!

【问题讨论】:

    标签: c# generics constructor activator


    【解决方案1】:

    只要你的构造函数看起来像这样,这应该对你有用:

    public MyType (Dictionary<string,object> dict)
    {
    }
    

    如果您的构造函数是非公开的,则需要更改 GetConstructor 以传入 BindingFlags.NonPublic。

            private T[] GetKeys<T>(string key, Dictionary<string, object> obj)
            // Since you're not using the default constructor don't need this:
            //   where T : new()
            {
                if (obj.ContainsKey(key))
                {
                    object[] objs = (object[])obj[key];
                    T[] list = new T[objs.Length];
                    for (int i = 0; i < objs.Length; i++)
                    {
                        list[i] = (T)typeof(T).GetConstructor(new [] {typeof(Dictionary<string,object>)}).Invoke (new object[] {
                                             (Dictionary<string, object>)objs[i] 
                                         });
                    }
                    return list;
                }
                else
                {
                    return null;
                }
            }
    

    【讨论】:

    • 理想情况下,我希望构造函数是内部的。但是,我对如何使用 GetConstructor 所需的附加参数并不满意,所以我想我现在只选择公共构造函数。
    【解决方案2】:

    您的 GetKeys 要求 T must have a public parameterless constructor:

    private T[] GetKeys<T>(...) where T : new()
                                           ↑
    

    这种对 T 的约束允许你在方法体中编写这样的代码:

    T t = new T();
    

    由于您没有使用它,但期望使用其他构造函数(不能像公共无参数构造函数那样强制执行),只需删除约束,它应该可以工作。

    【讨论】:

      【解决方案3】:

      由于您为使用此方法而在类中构建相似性,因此最好让它们都扩展相同的接口(或继承相同的基类,只要适合您的应用程序即可)。然后,您只需要使用传入的构造函数参数来构建基类列表。然后在调用代码中,您可以适当地转换列表项。

      【讨论】:

      • 不幸的是,构造函数是这些类之间的相似之处停止的地方。它们在 Dictionary 对象中传递,对于此方法的每次运行,该对象将具有完全不同的键。这些类也没有类似的属性或方法。每个类的构造函数以不同的方式检查和处理字典。
      猜你喜欢
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 1970-01-01
      相关资源
      最近更新 更多