【问题标题】:Constructor with optional parameter violates new() constraint具有可选参数的构造函数违反 new() 约束
【发布时间】:2014-04-30 14:08:38
【问题描述】:

我有一个带有这个构造函数的类:

public Currency(Guid? vcurrencyUI = null)
    : base(vcurrencyUI)
{ }

并且我想使用带有new() 约束的此类,但我收到此错误:

'Currency' 必须是具有公共无参数构造函数的非抽象类型,以便在泛型类型或方法中将其用作参数'T' ...

如果我拆分构造函数一切正常:

public Currency(Guid? vcurrencyUI)
    : base(vcurrencyUI)
{ }

public Currency()
    : base()
{ }

为什么要拆分构造函数?

【问题讨论】:

    标签: c# generics constructor constraints


    【解决方案1】:

    尽管 Jim already answered 你的问题,请注意,更通用的方法可能是允许传递一个 delegate 来实例化你的具体类,而不是强制你的所有实现都是无参数的。 p>

    即而不是这个:

    public class Something<T> where T : new()
    {
        public T CreateInstance()
        {
            return new T();
        }
    }
    

    您可以传递一个显式委托,该委托将执行任何自定义实例化逻辑:

    // note that the constraint is now removed
    public class Something<T>
    {
        private readonly Func<T> _ctor;
        public Something(Func<T> ctor)
        {
            _ctor = ctor;
        }
    
        public T CreateInstance()
        {
            return _ctor();
        }
    }
    
    // and you can now pass arbitrary constructor logic as a delegate
    var x = new Something<Currency>( () => new Currency(null) );
    

    这还允许您创建一个帮助类,并让这两个选项都可用:

    public class Something
    {
        // this allows you to use a parameterless ctor
        public static Something<T> Create<T>() where T : new()
        {
            return new Something<T>(() => new T());
        }
    
        // this allows you to specify a custom one
        public static Something<T> Create<T>(Func<T> ctor)
        {
            return new Something<T>(ctor);
        }
    }
    

    【讨论】:

      【解决方案2】:

      因为带默认参数的构造函数不是无参数构造函数。

      默认参数由编译器在编译时“填充”。当你写:

      var foo = new Currency();
      

      编译器生成:

      var foo = new Currency(null);
      

      当类被编译时,编译器会创建一个构造函数来接受 Guid? 参数,并生成一些元数据,实际上是“如果在编译时未提供参数,则提供 null”。但是没有为该类型生成无参构造函数。

      new() 约束要求为该类型定义无参数构造函数,并且它不接受具有单个默认参数的构造函数。这很可能是因为运行时(最终不得不调用构造函数)不理解默认参数的概念。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多