通用方法,其中T是type1或type2

时间:2011-12-18 15:52:41

标签: c# .net generics compiler-construction

有没有办法声明泛型函数的泛型类型是type1 还是 type2?

示例:

public void Foo<T>(T number)
{
}

我可以将T约束为int或long

7 个答案:

答案 0 :(得分:15)

虽然您可以使用generic constraint来限制每个泛型参数T的类型,但遗憾的是,没有任何一个允许您在编译时强制执行T是type1 or type2

也没有办法在编译时强制执行你的泛型参数只能是任何原始类型(int,long,double,...)。

答案 1 :(得分:15)

对于ReferenceType对象,您可以执行

error

...

public void DoIt<T>(T someParameter) where T : IMyType
{

}

对于使用long as参数的情况,无论如何都会将使用限制为long和int。

public interface IMyType
{
}

public class Type1 : IMyType
{
}

public class Type2 : IMyType
{
}

约束到你可以使用的任何值类型(如:int,double,short,decimal):

public void DoIt(long someParameter)
{

}

有关详细信息,请查看官方文档here

答案 2 :(得分:7)

没有

这没有意义; T在方法中没有任何可用的编译时类型。

相反,你应该制作两个重载方法。

答案 3 :(得分:5)

改为使用重载方法:

public void Foo(int number)
{
} 

public void Foo(long number)
{
}

无论如何,您无法对泛型类型执行算术运算。请注意,您可以将int值传递给long参数。它会自动转换为long。因此,只有一个带有long参数的方法就足够了。

旧的编程语言遵循“只能有一个”原则。 C#允许您在同一个类,接口或结构中使用多个具有相同名称的方法。这些方法必须具有不同的签名。这意味着它们必须具有不同数量的参数或具有不同类型(或两者)的参数。这称为方法重载。

答案 4 :(得分:1)

我知道这是一个老问题,但这并不能完美地回答它,但你可以用一个方法来做,而不是创建倍数,或使用通用约束......如果你有20个特别有用奇怪的类型要检查。

显然你没有像使用约束那样得到编译器类型检查,但这在某些情况下会有所帮助......

public void MyMethod<T>()
{
    if (!typeof(T).Equals(typeof(int)) &&
        !typeof(T).Equals(typeof(long)))
            throw new Exception("T must be int or long");

    //your logic here
}

答案 5 :(得分:0)

我认为目前不可能。

This question关于创建一个涵盖相同基础的数学库,包括一些解决方法。

答案 6 :(得分:0)

我也有这个问题,我认为我找到了一个更好的解决方案(假设你的方法的重载版本不足):

混合Type1Type2没有任何相似之处,这已经没有任何意义了。因此,必须为两种对象类型访问任何方法或属性。为了确保编译器可以为您的对象提供这些方法或属性,请通过创建接口Type1并按Type2和{{MyInterface实现它来对Type1Type2进行分组。 1}}:

interface MyInterface {
  void MyCommonMethod();
  bool MyCommonProperty { get; }
}

class Type1 : MyInterface {
  void MyCommonMethod() {
    // TODO: Implement it for Type1
  }

  bool MyCommonProperty {
  get {
    // TODO: Implement it for Type1
  }
  }
}

class Type2 : MyInterface {
  void MyCommonMethod() {
    // TODO: Implement it for Type2
  }

  bool MyCommonProperty {
  get {
    // TODO: Implement it for Type2
  }
  }
}

现在,要重写Foo方法以同时接受Type1Type2,请将T约束为MyInterface对象:

public void Foo<T>(T number) where T : MyInterface
{
  throw new NotImplementedException();
}

我莫测这可能会有所帮助。 :)