我正在处理一个项目,需要将整数转换为使用奇数字基(例如base36、62、64等)的字符串表示形式。在.NET Framework中并不支持这些奇数数字基(据我所知)。因此我们决定编写一个通用的字符串转换系统,可以与任何数字基一起工作,因为这是一个非常简单的操作。
稍后,我们想创建一个自定义的IFormatProvider / ICustomFormatter来方便以后的使用。但首先,我们需要解决转换过程本身,通过编写静态方法来执行转换并返回一些基本结果。一旦我们使其正常运行,我们将添加IFormatProvider包装器。
由于我已经有些时间没有使用C#泛型了,我无法记住如何让编译器满意这个操作。我想创建一个私有的静态泛型方法ConvertInteger,然后从公共静态Convert方法调用它,以帮助强制类型化而不会使其难以使用。这样做的主要原因之一是要避免在转换有符号值与无符号值时出现符号位问题。目前,我们有public static convert方法,适用于long和ulong,以避免在有符号和无符号值之间转换时出现问题。
将来,如果我们能够让私有的静态泛型方法正常工作,我们希望扩展公共方法,包括int、uint、short、ushort、byte和sbyte,作为显式实现,以帮助执行大批量不同整数大小的值的方法时提高性能。这就是泛型方法设计派上用场的地方,因此我们不必反复复制完全相同的代码(这也使测试和调试更加简单)。
我遇到的问题是,编译器不允许我使用泛型类型进行比较或数学运算,因为它不知道在提供泛型类型参数值之前如何执行这些操作。这让我感到非常难过,因为我主要是C ++开发人员,而C ++通过简单地避免在提供类型参数值之前尝试解释通用代码来解决了这个问题。
我需要做什么来满足泛型方法设计的编译器?下面是代码,并标注了特定的编译错误。
稍后,我们想创建一个自定义的IFormatProvider / ICustomFormatter来方便以后的使用。但首先,我们需要解决转换过程本身,通过编写静态方法来执行转换并返回一些基本结果。一旦我们使其正常运行,我们将添加IFormatProvider包装器。
由于我已经有些时间没有使用C#泛型了,我无法记住如何让编译器满意这个操作。我想创建一个私有的静态泛型方法ConvertInteger,然后从公共静态Convert方法调用它,以帮助强制类型化而不会使其难以使用。这样做的主要原因之一是要避免在转换有符号值与无符号值时出现符号位问题。目前,我们有public static convert方法,适用于long和ulong,以避免在有符号和无符号值之间转换时出现问题。
将来,如果我们能够让私有的静态泛型方法正常工作,我们希望扩展公共方法,包括int、uint、short、ushort、byte和sbyte,作为显式实现,以帮助执行大批量不同整数大小的值的方法时提高性能。这就是泛型方法设计派上用场的地方,因此我们不必反复复制完全相同的代码(这也使测试和调试更加简单)。
我遇到的问题是,编译器不允许我使用泛型类型进行比较或数学运算,因为它不知道在提供泛型类型参数值之前如何执行这些操作。这让我感到非常难过,因为我主要是C ++开发人员,而C ++通过简单地避免在提供类型参数值之前尝试解释通用代码来解决了这个问题。
我需要做什么来满足泛型方法设计的编译器?下面是代码,并标注了特定的编译错误。
public static class NumericStringConverter
{
private static readonly string[] StandardDigits = new string[]
{
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"_", "-"
};
private static string ConvertInteger<T>(T Value, T Base)
{
if (Base < 2) // error here: "Operator '<' cannot be applied to operands of type 'T' and 'int'"
throw new ArgumentOutOfRangeException("Base", Base, "The NumericStringConverter.Convert(Value, Base) method was called, with the Base parameter set to a value less than 2.");
if (Base > 64) // error here: "Operator '>' cannot be applied to operands of type 'T' and 'int'"
throw new ArgumentOutOfRangeException("Base", Base, "The NumericStringConverter.Convert(Value, Base) method was called, with the Base parameter set to a value greater than 64.");
if (Value == 0) // error here: "Operator '==' cannot be applied to operands of type 'T' and 'int'"
return StandardDigits[0];
string strResult = "";
bool IsValueNegative = (Value < 0); // error here: "Operator '<' cannot be applied to operands of type 'T' and 'int'"
while (Value != 0) // error here: "Operator '!=' cannot be applied to operands of type 'T' and 'int'"
{
strResult = strResult.Insert(0, StandardDigits[Math.Abs(Value % Base)]); // error here: "Operator '%' cannot be applied to operands of type 'T' and 'T'"
Value /= Base; // error here: "Operator '/=' cannot be applied to operands of type 'T' and 'T'"
}
if (IsValueNegative)
strResult = strResult.Insert(0, "-");
return strResult;
}
public static string Convert(long Value, long Base)
{
return ConvertInteger<long>(Value, Base);
}
public static string Convert(ulong Value, ulong Base)
{
return ConvertInteger<ulong>(Value, Base);
}
public static T Convert<T>(string Value, T Base)
{
return default(T); // TODO: convert a string back into an integer value.
}
}
IConvertible
但它也会允许浮点类型。我会将可以泛型化的部分进行泛型处理,并对不同的整数类型进行重载。 - D StanleyBase
必须是T
?如果它只允许值在2到64之间,为什么不能是byte
或其他整数类型? - D Stanleylong%byte
和long/= byte
不应该需要强制类型转换或其他转换。 - D Stanley