【问题标题】:Why can't I enforce derived classes to have parameterless constructors?为什么我不能强制派生类具有无参数构造函数?
【发布时间】:2011-02-08 18:02:04
【问题描述】:

我正在尝试执行以下操作:

class Program
{
    static void Main(string[] args)
    {
        foo<baz> fooObject = new foo<baz>();
        AnotherClass<baz> _baz = new AnotherClass<baz>();
        _baz.testMethod(fooObject);
    }
}

public class AnotherClass<T> where T : bar
{
    public void testMethod(foo<T> dummy)
    {
        foobar = dummy;
    }

    private foo<T> foobar = null;
}

public class foo<T> where T : bar, new()
{
    public foo()
    {
        _t = new T();
    }

    private T _t;

}

public abstract class bar
{
    public abstract void someMethod();
    // Some implementation
}

public class baz : bar
{
    public override void someMethod()
    {
        //Implementation
    }
}    

我收到一个错误,解释说“T”必须是具有公共无参数构造函数的非抽象类型才能将其用作泛型类型或方法中的参数“T”。我完全理解为什么必须这样做,并且也理解我可以将“T”类型的预初始化对象作为构造函数参数传递,以避免必须“新建”它,但是有什么办法解决这个问题吗?有什么方法可以强制从“bar”派生的类提供无参数构造函数?

已修复 - 我在 AnotherClass() 上缺少“new()”约束。

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    正确的语法是

    public class foo<T> where T : bar, new()
    

    【讨论】:

    • 抱歉,我打字太匆忙了。
    【解决方案2】:

    你不是在你的 AnotherClass 上缺少一个 new() 约束吗?

    public class AnotherClass<T> where T : bar, new()
    

    如果没有VS2010拒绝编译,它就可以正常工作。

    【讨论】:

    • 谢谢,这似乎已经解决了!
    【解决方案3】:

    您的代码在 VS2010 中编译。

    您可能想改用接口:

    public class foo<T> where T : ibar, new()
    ...
    
    public interface ibar
    {
        void someMethod();
    }
    
    public abstract class bar : ibar
    {
        public abstract void someMethod();
        // Some implementation
    }
    

    【讨论】:

      【解决方案4】:

      类似解决方法 - 您可以通过委托创建所需类型的实例:

        Func<T> creator = ...
      
        _t = creator();
      

      【讨论】:

        【解决方案5】:

        通用语法难道不是 new() 而不仅仅是 new?

        另外,你是在一个类的中间而不是在一个函数中编写这段代码,这肯定会让它感到困惑:

        _t = new T();
        

        编辑:

        好的,所以在语法清理之后,我猜问题是 'baz' 没有无参数构造函数。我不知道您可以通过任何方式强制执行此操作。

        有一个类似的问题here,可能会有所帮助。

        【讨论】:

        • “在类的中间”:这只是一个带有初始值的字段声明。
        • 已修复,谢谢。我半伪代码半真代码的坏习惯!
        【解决方案6】:

        首先从类“Foo”的关键字“where”中删除“new()” 之后必须将构造函数更改为

        public foo()
        {
            _t = Activator.CreateInstance<T>();
        }
        

        为我工作!

        【讨论】:

          猜你喜欢
          • 2012-08-23
          • 2011-09-27
          • 2022-01-17
          • 1970-01-01
          • 2020-07-02
          • 2012-09-28
          • 1970-01-01
          • 2011-02-24
          • 2021-03-07
          相关资源
          最近更新 更多