2012-10-09 43 views
6

我有一个接口ISnack,当它由类实现时,它应该有一个默认的无参数构造函数。基本上这个:有没有一种方法来执行没有通用约束的无参数构造函数

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

} 

我使用<T> where T : new()只是为了强制无参数的构造函数。

然后,我会实现这个接口是这样的:

public class Cutlet : ISnack<Cutlet> 
{ 

} 

这个工作,它只是确保Cutlet类有一个参数的构造函数。

现在我有一个抽象基类Kitchen

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

} 

的要求是:Kitchen应该有约束,其中T应该是一个ISnack但这不会工作,因为不存在ISnack,但只有ISnack<T>

如果我想这

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

} 

它不会编译('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>'),也将没有任何意义在我的上下文。

如果我能迫使ISnack s至具有参数的构造函数而不受T类型参数约束,那么在TKitchen<T>很容易被一个ISnack。如何去做呢?

回答

10

除非添加约束条件,否则不能这样做。通用约束是累积性的,所以使编译器高兴,你就必须有:

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

如果是罚款,然后做。如果不好,那么你必须从原来的: new删除,并没有它做。这并不像听起来那么糟糕,但它意味着你将验证推向执行而不是编译。但是:无论如何,Activator.CreateInstance<T>()仍然可以满足您的需求 - 即使没有new()限制。所以,你可以替换:

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

有:

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

一个方便的技巧,当除去约束可以是:增加一个单元/集成测试是通过反射发现候选类型,并验证缺少约束作为测试套件的一部分。

+0

Marc,Ditto!你已经概述了所有我已经试过..嗯运行时间是我的选择我猜我 – nawfal

+1

@nawfal如果没关系,你可以添加第二个通用的参数到厨房,这应该工作:'抽象类厨房其中T:ISnack S:new()' –

+0

@FelixK。你能否让它成为另一个答案? – nawfal

1

只需添加约束到T再次

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

您可以使用第二个泛型参数:

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

这将解决您的问题。

向类中添加第二个参数也可能会导致我在.NET 2.0可用后遇到的一些问题。一些复杂的情况可能需要添加更多的通用参数给类比你喜欢。通常情况下,我通过添加更多直接转换来分解通用链(如(SpecificType)base.MyTypeTProperty)。 评论:我试着在以后找到样品

+0

这也适用,但我认为它不如马克建议的那种优雅 – nawfal

+0

@nawfal当然,它可能在更复杂的情况下引发问题。我可能会在稍后发布一个例子。 –

相关问题