具有约束T(struct)和Nullable <t> </t>的泛型类

时间:2014-01-31 10:15:14

标签: c# generics type-constraints

我正在使用LinQ2SQL并使用数据绑定实现了用户控件来编辑不同实体的价格。

public partial class PriceControl<TDataSource, TPricesVat, TPriceNet, TPriceGross>
    : ANotifyPropertyXtraUserControl, IPriceControl<TDataSource, TPricesVat, TPriceNet, TPriceGross>
    where TDataSource : class, INotifyPropertyChanging, INotifyPropertyChanged
    where TPricesVat : struct
    where TPriceNet : struct
    where TPriceGross : struct
{
}

我喜欢同时使用decimaldecimal?两种类型。我正在使用代码语句来处理它们。但是C#不接受decimal?以便这些类型约束。我发现Nullable<T>也是struct,但不像struct那样完全支持。

是否有可能,如果是这样,如何在类型约束中实现这一点?我估计答案是“不”。但也许......

修改:我忘了提及,删除TPricesVatTPriceNetTPriceGross的约束让我可以正确编译此代码,但我没有在设计时强制允许通用类型的可能性。


编辑:由于我的工作,这个问题已被提出。但是在我离开后不久,我无法通过适当的解决方案来解决这个问题。尊重这个Q'n'A平台我在这里留下了这个编辑。

感谢所有有用的提及。

2 个答案:

答案 0 :(得分:1)

你的怀疑是正确的,你不能这样做。您必须为每种方法提供重载:

public partial class PriceControl<TDataSource, TPricesVat, TPriceNet, TPriceGross>
  : ANotifyPropertyXtraUserControl, IPriceControl<TDataSource, TPricesVat, TPriceNet, TPriceGross>
  where TDataSource : class, INotifyPropertyChanging, INotifyPropertyChanged
  where TPricesVat : struct
  where TPriceNet : struct
  where TPriceGross : struct
{

   public void DoSomething(TPriceNet price) {}
   public void DoSomething(TPriceNet? price)
   {
       if(price.HasValue)
           DoSomething(price.Value);
       else
       {
          //throw exception? log? no-op?
       }
   }
}

但是,和其他人一样,为什么要将这些类型约束到structbyteSpinWait可以是有效的TPriceNet吗?

答案 1 :(得分:0)

想象一下,有一种方法会收到decimal并返回decimal?,因为它也可以与intint?一起使用

public T? DoSomeMath<T>(T value)
   where T: struct
{
   //to return null you can do this
   return default(T);
   //or
   return null;
} 

注意方法声明中的?

使用struct和nullables时,这是最好的。

如果我可以约束where T: System.Nullable<T>,那就太好了。

但是这意味着一个悖论:如果TSystem.Nullable<T>并且我收到T作为参数,则意味着{{1在} T内部本身就是另一个System.Nullable<>

当然,如果你已经知道你将始终使用小数,那么就不需要使用泛型,只需直接使用System.Nullable<T>