2012-05-09 12 views
2

我有一个变量,其值在运行时填充。我想检查这个值是否在两个不同的数据类型值之间(比如说最低和最高),或者不使用扩展方法。在两个具有相同基类的数据类型之间创建扩展方法检查值

这两个值(最低和最高)可以是相同的数据类型(没问题)。然后,它像

public static bool Between<T>(this T actual, T lower, T upper) 
    where T : IComparable<T> 
{ 
    return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) <= 0; 
} 

礼貌我刚才问的问题How to create a Between Extension Method

但是,如果他们有不同的数据类型,但相同的基类的东西。

我想看看像

byte a = 2; //here static but is can be changed at runtime 

if(a.Between(0,8.0)) 
    DoSomething(); 
else 
    DoNothing(); 

在上面的代码中我检查一个int值和双值之间的字节值。在这种情况下如何做。我想创建一个像

public static bool Between<T1, T2, T3>(this T1 actual, T2 lowest, T3 highest) 
    where T1: ???? 
    where T2: ???? 
    where T3: ???? 
{ 
    What code to write here???? 
} 

扩展方法对于上面的代码中我的EM应该返回true

+0

在你的例子中写出* compilable *代码,当'T1'是'byte','T2'是'int'时,等等。看看这些代码,并考虑你有什么希望使其具有通用性。 – AakashM

+0

扩展方法是否应该拼写为'IsBetween'?听起来更好。 –

+0

@FelixK:它的扩展方法里面的代码在我的大脑里听起来更好。 –

回答

3

刚刚试了一下,我得到的最接近是这样的:

public static bool Between<T1, T2, T3>(this T1 actual, T2 lowest, T3 highest) 
    where T1: IComparable 
    where T2: IConvertible 
    where T3: IConvertible 
{ 
    return actual.CompareTo(lowest.ToType(typeof(T1), null)) >= 0 && 
      actual.CompareTo(highest.ToType(typeof(T1), null)) <= 0; 
} 

这将T2T3转换为T1,然后对它们进行比较。 如果lowesthighestT1类型转换失败,你会(如果T1bytelowerhighest255大为例)得到一个异常。 所以你可能想检查T1,如果需要,将actual转换为更大的数据类型。

1

如果通过数字类型,这是在CLR的一等公民工作,你不能有合同/接口自然适用于他们。是什么在我脑海中,是让所有的人都到大常见的数值类型和比较后,说():

public static bool Between(this byte actual, decimal lowest) 
{ 
    ... 
} 

使用后它喜欢:

if(a.Between(0,(decimal)8.0)) 
+0

我想你错过了EM的要点。如果这就是我想要做的,为什么它会写Ext.Met。以及我将如何继续转换每种可用的数据类型。 –

1
public static bool Between<T1, T2, T3>(this T1 actual, T2 lowest, T3 highest) 
where T1: T, IComparable<T> 
where T2: T 
where T3: T> 
{ 
return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) <= 0; 
} 

仅在T1上需要IComparable,因为只有实际(T1的实例)调用CompareTo。

检查基类约束: - >http://msdn.microsoft.com/en-us/library/d5x73970.aspx

+0

你试过了吗? T从哪里来?你知道它的可比性? –

+0

感谢您的指点,我错过了这一点,并只关注基于派生类型的问题 – Tilak

+1

如果您在约束中使用T,它必须出现在声明中

0

IComparable的需要被比较的Type相同Type作为Type被进行比较。因此,您需要具有与actuallowesthighest相同的Type

这意味着做这样的事情:

byte a = 2; 
decimal toCompare = (decimal)a; 

if(toCompare.Between(0.0, 8.0)) 
{ 
    DoSomething(); 
} 
else 
{ 
    DoNothing(); 
} 

如果尝试跨类型的比较,你会得到在运行时异常。

Console.WriteLine(1.CompareTo(2.0)); 

将导致异常被引发与消息'对象必须是类型Int32。'

+0

我认为你错过了点EM。如果这就是我想要做的,为什么它会写Ext.Met。以及我将如何继续转换每种可用的数据类型。 –

0

这并不是说优雅,但我会做的具体方法为通过的方式数值比较

public static bool BetweenNumeric<T1, T2, T3>(this T1 actual, T2 lowest, T3 highest) 
      where T1 : IConvertible 
      where T2 : IConvertible 
      where T3 : IConvertible 
     { 
      try 
      { 
       var actualDouble = Convert.ToDouble(actual); 
       var lowestDouble = Convert.ToDouble(lowest); 
       var highestDouble = Convert.ToDouble(highest); 
       return (actualDouble).CompareTo(lowestDouble) >= 0 && actualDouble.CompareTo(highestDouble) <= 0; 
      } 
      catch 
      { 
       return false; 
      } 
     } 

,如果该类型中的一个是布尔值,例如,它会被转换为1.0 ...而不是被捕获。

不完美,但你会避免吨的“类型检查”。

相关问题