检测通用参数的MaxValue
本文关键字:MaxValue 参数 检测 | 更新日期: 2023-09-27 18:27:21
我想写一个泛型类,它应该与byte
和ushort
类型一起使用。这个类应该使用什么约束?如何检测此类内部的MaxValue
属性?
class MyClass<T> // where T: ???
{
void Foo()
{
int maxValue = T.MaxValue; // how can I do this?
}
}
若类是用不包含MaxValue属性的意外类型创建的,我不在乎——例如,我可以在运行时抛出异常。
一种方法是利用新的dynamic
关键字:
void Main()
{
Test(10);
Test(10.234);
Test((Byte)42);
Test(true);
}
public void Test<T>(T value)
where T : struct
{
T maxValue = MaxValue((dynamic)value);
maxValue.Dump();
}
public int MaxValue(int dummy)
{
return int.MaxValue;
}
public double MaxValue(double dummy)
{
return double.MaxValue;
}
public byte MaxValue(byte dummy)
{
return byte.MaxValue;
}
public object MaxValue(object dummy)
{
// This method will catch all types that has no specific method
throw new NotSupportedException(dummy.GetType().Name);
}
或者,您可以使用反射来获得MaxValue字段:
void Main()
{
Test(10);
Test(10.234);
Test((Byte)42);
Test(true);
}
public void Test<T>(T value)
where T : struct
{
FieldInfo maxValueField = typeof(T).GetField("MaxValue", BindingFlags.Public
| BindingFlags.Static);
if (maxValueField == null)
throw new NotSupportedException(typeof(T).Name);
T maxValue = (T)maxValueField.GetValue(null);
maxValue.Dump();
}
您可以通过LINQPad测试这两个程序。
试试这样的
public T GetMaxValue()
{
object maxValue = default(T);
TypeCode typeCode = Type.GetTypeCode(typeof(T));
switch (typeCode)
{
case TypeCode.Byte:
maxValue = byte.MaxValue;
break;
case TypeCode.Char:
maxValue = char.MaxValue;
break;
case TypeCode.DateTime:
maxValue = DateTime.MaxValue;
break;
case TypeCode.Decimal:
maxValue = decimal.MaxValue;
break;
case TypeCode.Double:
maxValue = decimal.MaxValue;
break;
case TypeCode.Int16:
maxValue = short.MaxValue;
break;
case TypeCode.Int32:
maxValue = int.MaxValue;
break;
case TypeCode.Int64:
maxValue = long.MaxValue;
break;
case TypeCode.SByte:
maxValue = sbyte.MaxValue;
break;
case TypeCode.Single:
maxValue = float.MaxValue;
break;
case TypeCode.UInt16:
maxValue = ushort.MaxValue;
break;
case TypeCode.UInt32:
maxValue = uint.MaxValue;
break;
case TypeCode.UInt64:
maxValue = ulong.MaxValue;
break;
default:
maxValue = default(T);//set default value
break;
}
return (T)maxValue;
}
您只能使用struct
作为约束,它只允许T
的值类型。作为约束的每个特定值类型都将被编译器拒绝。因此,您必须在运行时检查T
是否是您允许的类型之一。
获得(未知)类型T
的MaxValue
的唯一方法是使用以下内容进行反射:
typeof(T).GetField("MaxValue").GetValue(null);
好吧,这是没有限制的,正如我从这里和我读过的其他地方总结的那样。
hoever,您可以使用一个接口包装ushort和byte:
public interface IReturnUShortAndBytes
{
ushort ReturnUShortsOrZero();
byte ReturnByteOrZero();
}
这不是最好的东西,但它可能会起作用,这取决于你需要什么
该约束在C#中是不可能的。您可以通过特定的接口(如)约束到值类型
where T : struct, IComparable, IFormattable,
IConvertible, IComparable<T>, IEquatable<T>
不幸的是,这将匹配比你想要的更多的类型。并且MaxValue
不是任何接口的成员(它是一个字段!),所以约束在这里对您没有帮助。你可能想在费罗的回答中使用反思。