现在,我知道你可以通过where子句将通用类型参数限制为类型或接口实现。然而,这不适用于原始类型(AFAIK),因为它们没有共同点(除了对象之外,有人可能会说!:P)。
所以,我目前的想法是只需刚毅地执行一个大switch语句,并在失败时抛出ArgumentException。
编辑1:
只是为了澄清:
代码定义应该像这样:
public class MyClass<GenericType> ....
实例化:
MyClass<bool> = new MyClass<bool>(); // Legal
MyClass<string> = new MyClass<string>(); // Legal
MyClass<DataSet> = new MyClass<DataSet>(); // Illegal
MyClass<RobsFunkyHat> = new MyClass<RobsFunkyHat>(); // Illegal (but looks awesome!)
编辑2
@Jon Limjap - 很好的观点,这也是我已经在考虑的事情。我相信有一种通用的方法可以用来确定类型是值类型还是引用类型。
这可能对立即删除我不想处理的许多对象有用(但然后你需要担心使用的结构,比如Size)。有趣的问题,不是吗? :)
这就是它:
where T: struct
本文摘自MSDN。
我很好奇,.NET 3.x能否使用扩展方法来完成这个操作?创建一个接口,并在扩展方法中实现该接口(这可能比一个大而臃肿的开关更干净)。此外,如果您以后需要扩展任何轻量级自定义类型,则它们也可以实现相同的接口,而不需要对基本代码进行任何更改。
你们觉得怎么样?
可悲的消息是,我正在使用Framework 2! :D
第三次编辑
这是跟随Jon Limjaps Pointer之后非常简单的事情。如此简单,我几乎要哭了,但它很棒,因为代码运行得像魅力一样!
所以这就是我做的(你会笑!):
添加到通用类的代码
bool TypeValid()
{
// Get the TypeCode from the Primitive Type
TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));
// All of the TypeCode Enumeration refer Primitive Types
// with the exception of Object and Empty (Null).
// Since I am willing to allow Null Types (at this time)
// all we need to check for is Object!
switch (code)
{
case TypeCode.Object:
return false;
default:
return true;
}
}
接下来是一个小工具方法,用于检查类型并抛出异常。
private void EnforcePrimitiveType()
{
if (!TypeValid())
throw new InvalidOperationException(
"Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name +
"' - this Class is Designed to Work with Primitive Data Types Only.");
}
现在需要做的就是在类的构造函数中调用EnforcePrimitiveType()。工作完成!:-)
唯一的缺点是它只会在运行时(显然)抛出异常,而不是在设计时。但这并不是什么大问题,可以使用像FxCop这样的工具来解决(我们在工作中没有使用过)。
特别感谢Jon Limjap!