在回顾这里的答案后,我有一点点玩弄自己,我已经出现了与下面的实现,它检查运行时约束而不是编译时间。
// This example takes 3 parameters...
public class GenericConstraint<T1, T2, T3>
{
public GenericConstraint(Type type)
{
if (!(type is T1) || !(type is T2) || !(type is T3))
{
throw new Exception("This is not a supported type");
}
}
}
现在我继承了我的自定义类...
public class Custom<T> : GenericConstraint<string, int, byte>
{
public Custom() : base(typeof(T))
{
}
}
现在,这将引发一个错误:
Custom<long> item = new Custom<long>();
这不!
Custom<byte> item2 = new Custom<byte>();
正如Marc Gravell所述,这不是继承或泛型的好用法。通过继承GenericConstraint从逻辑上思考,这只是限制继承,并且也没有正确使用类型层次结构。就泛型的使用而言,这实际上毫无意义!
因此,我有另一个解决方案作为一个辅助方法来限制运行时的类型。这从继承中释放了对象,因此对类型层次结构没有影响。
public static void ConstrainParameterType(Type parameterType, GenericConstraint constraintType, params Type[] allowedTypes)
{
if (constraintType == GenericConstraint.ExactType)
{
if (!allowedTypes.Contains<Type>(parameterType))
{
throw new Exception("A runtime constraint disallows use of type " + parameterType.Name + " with this parameter.");
}
}
else
{
foreach (Type constraint in allowedTypes)
{
if (!constraint.IsAssignableFrom(parameterType))
{
throw new Exception("A runtime constraint disallows use of type " + parameterType.Name + " with this parameter.");
}
}
}
}
public enum GenericConstraint
{
/// <summary>
/// The type must be exact.
/// </summary>
ExactType,
/// <summary>
/// The type must be assignable.
/// </summary>
AssignableType
}
现在这允许在普通对象的多个类型的限制,即使类型密封等
"public class Custom where T : string ... is not allowed, because the only T that meets that is: string (string is sealed) - making it rather pointless as a generic."
是的,这是没有意义的,但在某些情况下,您可能希望将对象约束允许,例如;字符串,StringBuilder和SecureString。虽然这不提供编译时间约束,但它确实提供了运行时约束,并且在约束中可以使用哪些类型的一些灵活性。
为这些情况做的最好的事情是创建一个包装类,或者采用更通用的东西(Object),并在构造函数中进行类型检查。这很漂亮吗?没有。它会工作吗?是。 – sybkar
@sybkar,你的意思就像我的回答? – series0ne