C# 是否有一种技术可以区分泛型类型上的类行为?

C# 是否有一种技术可以区分泛型类型上的类行为?,c#,generics,type-constraints,C#,Generics,Type Constraints,我想做如下的事情,但因为T本质上只是一个系统。我知道T可以被接口约束,但这不是一个选项 public class Vborr<T> where T : struct { public Vborr() { public T Next() { if ( typeof( T ) == typeof( Double ) ) { // do something for doubles } i

我想做如下的事情,但因为T本质上只是一个系统。我知道T可以被接口约束,但这不是一个选项

public class Vborr<T> where T : struct
  {

    public Vborr()
    {
    public T Next()
    {
      if ( typeof( T ) == typeof( Double ) )
      {
         // do something for doubles
      }
      if ( typeof( T ) == typeof( Float ) )
      {
         // do something different for floats..
      }
    }
  }
公共类Vborr,其中T:struct
{
公共Vborr()
{
公共交通工具
{
如果(类型(T)=类型(双))
{
//为双打做点什么
}
如果(类型(T)=类型(浮动))
{
//为花车做些不同的事情。。
}
}
}
我经常发现缺乏C#泛型

谢谢


Paul

泛型的全部要点是,您可以对任何有效类型执行相同的操作

如果您确实在为类型执行特定的操作,那么该方法就不再是泛型的,应该为每个特定类型重载

public class Vborr<T> where T : struct
{
    public virtual T Next() { // Generic Implementation }
}

public class VborrInt : Vborr<int>
{
    public override int Next() { // Specific to int }
}

public class VborrDouble : Vborr<double>
{
    public override double Next() { // Specific to double }
}
公共类Vborr,其中T:struct
{
公共虚拟T Next(){//Generic Implementation}
}
公共类VborrInt:Vborr
{
公共覆盖int Next(){//特定于int}
}
公共类VborrDouble:Vborr
{
public override double Next(){//特定于double}
}

我在这里采用的方法是工厂模式,并根据类型创建
Vborr
的专门实例

public class Vborr<T> where T : struct {
  protected Vborr() { }
  abstract T Next();
}

public static class VborrFactory { 
  private sealed class VborrFloat : Vborr<float> {
    public VborrFloat() {}
    public override float Next() {
      ...
    }
  }
  private sealed class VborrDouble : Vborr<double> {
    public VborrDobule() {}
    public override double Next() {
      ...
    }
  }
  private sealed class VborrDefault<U> : Vborr<U> {
    public VborrDefault() {}
    public override U Next() {
      ...
    }
  }
  public static Vborr<T> Create<T>() {
    if (typeof(T) == typeof(double) ) { 
      return new VborrDouble();
    } else if ( typeof(T) == typeof(float) ) {
      return new VborrFloat();
    } else {
      return new VborrDefault<T>();
    }
  }
}
公共类Vborr,其中T:struct{
受保护的Vborr(){}
抽象T Next();
}
公共静态类VborrFactory{
专用密封类Vborr浮动:Vborr{
公共VborrFloat(){}
公共覆盖浮动下一步(){
...
}
}
专用密封等级VborrDouble:Vborr{
公共VborrDobule(){}
公共覆盖双下一步(){
...
}
}
私有密封类Vborr默认值:Vborr{
公共VborrDefault(){}
公共覆盖U Next(){
...
}
}
公共静态Vborr Create(){
如果(typeof(T)=typeof(double)){
返回新的VborrDouble();
}否则如果(类型(T)=类型(浮动)){
返回新的VborrFloat();
}否则{
返回新的VborrDefault();
}
}
}

为什么它不起作用?你想做什么?我不是说这是个好主意,但这段代码应该可以按原样编译(一旦你修复了拼写错误)。你的问题在哪里?你的ifs按类型区分行为,所以你已经找到了解决方案。如果你的浮点转换…失败,你可以尝试(浮点)(对象)x、 但是我不确定这是否符合要求。从您提供的两个案例来看,听起来您是在寻找
where T:INumeric
还是什么?我希望我们可以有这样一个功能,但我认为这不会很快发生。Ani:MiscUtil中的运算符类提供了这一点。与非泛型代码相比,性能相当差不过,因为它需要对每个运算符进行lambda调用。这取决于您要执行的操作。在double和float的特定示例中,它们都实现了IFormattable、IConvertible、IComparable和IEquatable。因此,如果您想进行一些对象转换,例如,与其说if(TypeOf(T)=TypeOf(double)),不如说if(TypeOf(T)==TypeOf(IConvertible)),然后利用IConvertible接口。在某些情况下,可以作为性能优化来避免接口或lambda调用。例如,MiscUtil中的运算符类可以从中获益。是的,这一点很好。但因为对于调用public T Next()的用户来说double或float的行为在功能上是相同的。它们不必处理两个类(在C#……中不能重载返回类型,只有在IL中才有可能)为了解决最后一点,您可以创建一个VborFactory类,该类将向用户返回正确的子类,用户可以将其视为Vborr,而不关心它实际上是一个Vborrit或VborrDouble或其他任何东西。我也给Justin一个答案,因为提醒这一点并没有什么坏处。但是,在一些特殊情况下,有些不同的在这种情况下,单次/双次之间的性能差异很大,这是用户唯一关心的问题。