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;
}

礼貌我之前提出的问题如何创建之间的扩展方法

但是,如果它们具有不同的数据类型但具有相同的基类怎么办。

我想检查一下

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

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

在上面的代码片段中,我正在检查 int 值和 double 值之间的字节值。这种情况下怎么办。我想创建一个扩展方法,例如

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

4

5 回答 5

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;
}

这会将T2and转换T3T1,然后将它们进行比较。如果lowestorhighest类型的转换T1失败,你会得到一个异常(例如 if T1is byteand loweror highestare greater than 255)。因此,您可能需要检查T1,并在需要时转换actual为更大的数据类型。

于 2012-05-09T08:36:32.017 回答
1

如果您对数字类型(它们是 CLR 中的一等公民)进行操作,那么您自然不能将合同/接口应用于它们。我想到的是将所有这些都带入更大的通用数字类型并在之后进行比较,例如(伪代码):

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

并在使用后像:

if(a.Between(0,(decimal)8.0))
于 2012-05-09T08:06:16.587 回答
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

于 2012-05-09T08:06:32.693 回答
0

IComparable 要求被比较的对象与Type被比较对象相同。因此,您将需要与和相同。TypeTypeTypeactuallowesthighest

这意味着做这样的事情:

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

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

如果您尝试跨类型进行比较,您将在运行时遇到异常。

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

将导致抛出异常并显示消息“对象必须是 Int32 类型。”

于 2012-05-09T08:09:03.840 回答
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... 而不是被捕获。

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

于 2012-05-09T08:14:16.067 回答