简体   繁体   English

有没有办法在没有通用约束的情况下强制执行无参数构造函数

[英]Is there a way to enforce parameterless constructor without generic constraint

I have an interface ISnack which when implemented by a class, it should have a default parameterless constructor. 我有一个接口ISnack ,当由类实现时,它应该有一个默认的无参数构造函数。 Basically this: 基本上这个:

public interface ISnack<T> where T : new()
{

}

I use <T> where T : new() just to enforce the parameterless constructor. 我使用<T> where T : new()只是为了强制执行无参数构造函数。

I would then implement the interface this way: 然后我会以这种方式实现接口:

public class Cutlet : ISnack<Cutlet>
{

}

This works and it simply ensures Cutlet class has a parameterless constructor. 这有效,它只是确保Cutlet类具有无参数构造函数。

Now I have an abstract base class Kitchen : 现在我有一个抽象基类Kitchen

public abstract class Kitchen<T> where T : ISnack
{

}

The requirement is that Kitchen should have constraint where T should be an ISnack . 要求是Kitchen应该有一个约束,其中T应该是一个ISnack But this wont work because there exists no ISnack , but only ISnack<T> . 但这不会起作用,因为没有ISnack ,只有ISnack<T>

If I tried this 如果我试过这个

public abstract class Kitchen<T> where T : ISnack<T>
{

}

it wouldn't compile ( 'T' 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 'ISnack<T>' ) and also wouldn't make sense in my context. 它不会编译( 'T' 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 'ISnack<T>' )并且也不会在我的背景下感觉。

If I could force ISnack s to have a parameterless constructor without constraining by a T type parameter, then T in Kitchen<T> could easily be an ISnack . 如果我能迫使ISnack s至具有参数的构造函数而不受约束T类型参数,然后TKitchen<T>很容易被一个ISnack How to go about it? 怎么去呢?

You can't unless you add the constraint; 除非添加约束,否则不能; generic constraints are cumulative, so to make the compiler happy you would have to have: 泛型约束是累积的,因此要使编译器满意,您必须具有:

public abstract class Kitchen<T> where T : ISnack<T>, new()

If that is fine, then do that . 如果没关系, 那就去做吧 If it isn't fine, then you'll have to remove the : new from the original, and make do without it. 如果它不好,那么你将不得不从原版中删除: new ,并且不使用它。 This isn't as bad as it sounds, but it means you push validation down to execution rather than compilation. 这并不像听起来那么糟糕,但它意味着您将验证推送到执行而不是编译。 But: Activator.CreateInstance<T>() still does what you would need, anyway - even without the new() constraint. 但是:即使没有new()约束, Activator.CreateInstance<T>()仍然会做你需要的东西。 So you can replace: 所以你可以替换:

T newObj = new T(); // validated by the compiler

with: 有:

T newObj = Activator.CreateInstance<T>(); // not validated until executed

A handy trick when removing constraints can be: add a unit/integration test that finds the candidate types via reflection, and validate the missing constraint as part of your test suite . 删除约束时的一个方便技巧可以是:添加通过反射查找候选类型的单元/集成测试,并将缺少的约束验证为测试套件的一部分

You can use a second generic parameter: 您可以使用第二个通用参数:

abstact class Kitchen<T, S> 
    where T : ISnack<S> 
    where S : new()
....

This will solve your issue. 这将解决您的问题。

Adding a second parameter to a class also can cause some issues which i've faced since .NET 2.0 is available. 向类中添加第二个参数也可能导致我在.NET 2.0可用时遇到的一些问题。 Some complex situations may require to add more generic parameters to classes than you like to. 某些复杂情况可能需要向类添加比您更喜欢的更多通用参数。 Normally i break down the generic chain by adding more direct casts ( like (SpecificType)base.MyTypeTProperty ). 通常我通过添加更多直接强制转换(如(SpecificType)base.MyTypeTProperty )来分解泛型链。 Comment: I try to find a sample later 评论:我试着稍后找一个样本

只需再次将约束添加到T.

public abstract class Kitchen<T> where T : ISnack<T>, new()   {      }

暂无
暂无

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

相关问题 通用约束:强制类型具有静态函数和带参数的构造函数 - Generic constraint: Enforce type to have static function and constructor with parameters 有没有办法让以前公开的无参数构造函数私有化,而不会对 protobuf(反)序列化进行重大更改? - Is there a way to make a previously-public parameterless constructor private without making it a breaking change for protobuf (de)serialization? C# 序列化一个没有无参数构造函数的类 - C# serialize a class without a parameterless constructor 如何将对象强制转换为具有公共无参数构造函数以遵守:new()约束? - How to cast an object as having a public parameterless constructor to respect a : new() constraint? 具有字符串参数的Constructor的通用约束? - Generic constraint for Constructor with string argument? 具有新类型约束的泛型构造函数 - Generic constructor with new type constraint 为什么此通用方法要求T具有公共的无参数构造函数? - Why does this generic method require T to have a public, parameterless constructor? 无参数DbContext和DbContextFactory构造函数的Add-Migration - Add-Migration without parameterless DbContext and DbContextFactory constructor 注入没有无参数构造函数的第三方类 - Inject third-party class without parameterless constructor 使用NInject在WPF中注入没有无参数构造函数的viewmodel类 - injecting viewmodel class without parameterless constructor in WPF with NInject
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM