我想编写应该使用byte
和ushort
类型的泛型类。我应该为这门课使用什么约束?如何在此类中检测MaxValue
属性?
class MyClass<T> // where T: ???
{
void Foo()
{
int maxValue = T.MaxValue; // how can I do this?
}
}
如果使用意外类型创建了类,它不包含MaxValue属性,我不在乎 - 例如,我可以在运行时抛出异常。
答案 0 :(得分:9)
一种方法是利用新的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测试这两个程序。
答案 1 :(得分:5)
尝试这样的事情
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;
}
答案 2 :(得分:2)
您只能使用struct
作为约束,只允许T
的值类型。作为约束的每个特定值类型将被编译器拒绝。因此,您必须检查T
是否是您允许的类型之一。
获取(未知)类型MaxValue
的{{1}}的唯一方法是使用以下内容进行反映:
T
答案 3 :(得分:0)
然而,您可以使用接口包装ushort和byte:
public interface IReturnUShortAndBytes
{
ushort ReturnUShortsOrZero();
byte ReturnByteOrZero();
}
这不是最好的事情,但它可以完成工作,取决于你需要什么
答案 4 :(得分:0)
在C#中无法实现该约束。您可以使用特定接口约束值类型,例如
where T : struct, IComparable, IFormattable,
IConvertible, IComparable<T>, IEquatable<T>
不幸的是,这将匹配比您想要的更多类型。并且MaxValue
不是任何接口的成员(它是一个字段!),因此约束对此没有帮助。您可能希望在fero的答案中使用反射。