简体   繁体   English

带有可选参数的构造函数违反new()约束

[英]Constructor with optional parameter violates new() constraint

I have a class with this constructor: 我有一个这个构造函数的类:

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

and I want to use this class with a new() constraint but I get this error: 我想使用new()约束这个类,但我得到这个错误:

'Currency' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method ... 'Currency'必须是具有公共无参数构造函数的非抽象类型,才能在泛型类型或方法中将其用作参数'T'...

If I split the constructor everything works fine: 如果我拆分构造函数一切正常:

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

public Currency()
    : base()
{ }

why do I need to split the constructor? 为什么我需要拆分构造函数?

Because a constructor with a default parameter is not a parameterless constructor. 因为具有默认参数的构造函数不是无参数构造函数。

Default parameters are "filled in" by the compiler at compile time. 编译器在编译时“填充”默认参数。 When you write: 当你写:

var foo = new Currency();

The compiler generates: 编译器生成:

var foo = new Currency(null);

When the class is compiled, the compiler creates a constructor that takes that Guid? 编译类时,编译器会创建一个带有Guid?的构造函数Guid? parameter, and also generates some metadata that says in effect "if the parameter isn't supplied at compile time, then supply null ." 参数,并且还生成一些有效的元数据“如果在编译时未提供参数,则提供null But no parameterless constructor is generated for the type. 但是没有为该类型生成无参数构造函数。

The new() constraint requires that a parameterless constructor be defined for the type, and it won't accept a constructor with a single default parameter. new()约束要求为该类型定义无参数构造函数,并且它不接受具有单个默认参数的构造函数。 Most likely that's because the runtime, which ends up having to call the constructor, doesn't understand the concept of default parameters. 很可能是因为运行时最终不得不调用构造函数,因此无法理解默认参数的概念。

Although Jim already answered your question, note that a more general approach might be to allow passing a delegate which would instantiate your concrete class, instead of forcing all your implementations to be parameterless. 虽然Jim 已经回答了你的问题,但请注意,更通用的方法可能是允许传递一个委托 ,它将实例化你的具体类,而不是强制所有的实现都是无参数的。

Ie instead of this: 即代替这个:

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

You can pass an explicit delegate which will do any custom instantiation logic: 您可以传递一个显式委托,它将执行任何自定义实例化逻辑:

// 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) );

This also allows you to create a helper class and have both options readily available: 这也允许您创建一个帮助程序类,并提供两个选项:

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 GenericArguments[0], &#39;EntityGenericBase`1[TModel]&#39; 违反了类型参数 &#39;TModel&#39; 的约束 - ‏GenericArguments[0], 'EntityGenericBase`1[TModel]' violates the constraint of type parameter 'TModel' “ BinaryNode`2 [N,T]”上的GenericArguments [1],“ T”违反了类型参数“ T”的约束 - GenericArguments[1], 'T', on 'BinaryNode`2[N,T]' violates the constraint of type parameter 'T' ASP Core 违反了 String 类型参数“TRole”的约束 - ASP Core violates the constraint of type parameter 'TRole' for String Unity配置文件-GenericArguments违反了类型参数的约束 - Unity configuration file - GenericArguments violates the constraint of type parameter 绑定中的Azure功能表存储违反类型参数&#39;TElement&#39;的约束 - Azure Function Table Storage in binding violates the constraint of type parameter 'TElement' MyGeneric1 [T]上的GenericArguments [0],TestClass违反类型参数&#39;T&#39;的约束 - GenericArguments[0], TestClass, on MyGeneric1[T] violates the constraint of type parameter 'T' 具有新类型约束的泛型构造函数 - Generic constructor with new type constraint 受保护的构造函数:where new() 约束 - Protected constructor for :where new() constraint 带有可选参数的构造函数会重载吗? - Does constructor with optional-parameter overload it? C# 中是否有带参数约束的泛型构造函数? - Is there a generic constructor with parameter constraint in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM