当前位置:  开发笔记 > 编程语言 > 正文

通用类型检查

如何解决《通用类型检查》经验,为你挑选了3个好方法。

有没有办法强制/限制传递给基元的类型? (bool,int,string等)

现在,我知道您可以通过where子句将泛型类型参数限制为类型或接口实现.然而,这不符合基元(AFAIK)的费用,因为它们并非都有共同点(除了某人之前的对象!:P).

所以,我目前的想法只是咬紧牙关并做一个大的switch语句并在失败时抛出ArgumentException.


编辑1:

只是为了澄清:

代码定义应该是:

public class MyClass ....

和实例化:

MyClass = new MyClass(); // Legal
MyClass = new MyClass(); // Legal
MyClass = new MyClass(); // Illegal
MyClass = new MyClass(); // Illegal (but looks awesome!)

编辑2

@Jon Limjap - 好点,我正在考虑的事情......我确信有一个通用的方法可以用来确定类型是值还是引用类型..

这可以用于立即删除我不想处理的很多对象(但是你需要担心使用的结构,比如Size).有趣的问题不是吗?:)

这里是:

where T : struct

取自MSDN.


我很好奇..可以使用扩展方法在.NET 3.x中完成吗?创建一个接口,并在扩展方法中实现接口(这可能比胖胖的开关更干净).此外,如果您稍后需要扩展到任何轻量级自定义类型,它们也可以实现相同的接口,而不需要对基本代码进行任何更改.

你们有什么感想?

可悲的消息是我在Framework 2中工作!! :d


编辑3

从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在这一个!



1> Lars Mæhlum..:
public class Class1 where GenericType : struct
{
}

这个似乎做了这个工作..



2> Jon Limjap..:

原始似乎在TypeCode枚举中指定:

也许有一种方法可以找出一个对象是否包含TypeCode enum无需将其转换为特定对象或调用GetType()typeof()

更新它在我的鼻子底下.那里的代码示例显示了这一点:

static void WriteObjectInfo(object testObject)
{
    TypeCode    typeCode = Type.GetTypeCode( testObject.GetType() );

    switch( typeCode )
    {
        case TypeCode.Boolean:
            Console.WriteLine("Boolean: {0}", testObject);
            break;

        case TypeCode.Double:
            Console.WriteLine("Double: {0}", testObject);
            break;

        default:
            Console.WriteLine("{0}: {1}", typeCode.ToString(), testObject);
            break;
        }
    }
}

它仍然是一个丑陋的开关.但这是一个开始的好地方!



3> Keith..:

几乎是@Lars已经说过的话:

//Force T to be a value (primitive) type.
public class Class1 where T: struct

//Force T to be a reference type.
public class Class1 where T: class

//Force T to be a parameterless constructor.
public class Class1 where T: new()

所有工作都在.NET 2,3和3.5中完成.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有