首页 新闻 会员 周边 捐助

泛类型的几个问题求解

0
悬赏园豆:5 [已解决问题] 解决于 2014-08-26 09:20

1、如何判断一个类型是否是泛类型的派生类?

比如:

int? i = 1;

bool compatible = typeof(Nullable<>).IsAssignableFrom(i.GetType());

此时 compatible 是false。

2、已知一个类型是泛类型,如何获取这个泛类型的类型参数?

比如:

int? i = 1;

Type t = i.GetType();

如何通过 "t" 获得类型 "int" ?

3、如何使用泛型基础类型的属性、方法对象对具体的泛型对象进行操作?

比如:

var t = typeof(Nullable<>);

var p = t.GetProperty("Value");

int? i = 1;

var v = p.GetValue(i);

这里执行最后一条的时候是不能通过的。

问题补充:

写了个扩展,暂时能满足别的需求,但对Nullable还是无奈:

    public static class Extensions
    {
        public static bool IsCompatibleToGenericType(this Type source, Type genericType)
        {
            if(genericType.IsAssignableFrom(source))
            {
                return true;
            }
            if(!genericType.IsGenericType)
            {
                return false;
            }
            if(genericType.IsClass && source.IsInterface)
            {
                return false;
            }
            if (!genericType.ContainsGenericParameters)
            {
                genericType = genericType.GetGenericTypeDefinition();
            }
            if (genericType.IsInterface || source.IsInterface)
            {
                var interfaces = source.GetInterfaces();
                foreach (var @interface in interfaces)
                {
                    if (@interface.GetGenericTypeDefinition() == genericType)
                    {
                        return true;
                    }
                }
            }
            else
            {
                while (source != typeof(object))
                {
                    if (source.IsGenericType)
                    {
                        if (source.GetGenericTypeDefinition() == genericType)
                        {
                            return true;
                        }
                    }
                    source = source.BaseType;
                }
            }
            return false;
        }

        public static Type[] GetCompatibleGenericTypeParameterTypes(this Type source, Type genericType)
        {
            if(!genericType.IsGenericType || !source.IsCompatibleToGenericType(genericType))
            {
                return new Type[0];
            }
            if (!genericType.ContainsGenericParameters)
            {
                genericType = genericType.GetGenericTypeDefinition();
            }
            if (genericType.IsInterface || source.IsInterface)
            {
                var interfaces = source.GetInterfaces();
                foreach (var @interface in interfaces)
                {
                    if (@interface.GetGenericTypeDefinition() == genericType)
                    {
                        return @interface.GetGenericArguments();
                    }
                }
            }
            else
            {
                while (source != typeof(object))
                {
                    if (source.IsGenericType)
                    {
                        if (source.GetGenericTypeDefinition() == genericType)
                        {
                            return source.GetGenericArguments();
                        }
                    }
                    source = source.BaseType;
                }
            }
            return new Type[0];
        }
    }
519740105的主页 519740105 | 大侠五级 | 园豆:5810
提问于:2014-08-07 09:37
< >
分享
最佳答案
0
收获园豆:1
Launcher | 高人七级 |园豆:45050 | 2014-08-07 11:09

@XiaoFaye: 谢谢。你的这个帖子已经是我通过对Type类型进行分析后的可控方案,但有个新的问题,如你贴的URL里所说,Nullable<>的类型,通过GetType后,返回的是泛类型参数的类型,如:

int? a;//用Nullable<int>定义是一样的

a.GetType()返回的是int

这里,我又应该怎么去判断当前传递进来的对象是否是Nullable<>兼容的呢?

谢谢。

519740105 | 园豆:5810 (大侠五级) | 2014-08-07 11:29

@519740105: 你能给我写段代码说明你需要"判断当前传递进来的对象是否是Nullable<>兼容"的例子吗?

Launcher | 园豆:45050 (高人七级) | 2014-08-07 14:47

@Launcher: 没什么特殊的代码,就是下面这样:

int? i = 1;

Type type = i.GetType();

此时,获得的type是int而不是我要的Nullable<int>

519740105 | 园豆:5810 (大侠五级) | 2014-08-07 15:27

@519740105: 既然这样,那我就你这段代码来说:

看你的第一句:int? i = 1,

既然你已经知道是 int? 类型了,那么你的下一行代码就可以这样写: Type type = typeof(int?);

因为我想知道的问题是,是什么原因造成你无法使用我给的这条语句,而必须使用 i.GetType() ?

Launcher | 园豆:45050 (高人七级) | 2014-08-07 15:34

@Launcher: 只是举例子,最后的这个变量i是要传递给一个函数,比如:

void Main()

{

int? i = 1;

Process(i);

}

void Porcess(object @object)

{

    var type = @object.GetType();//type为:int

}

519740105 | 园豆:5810 (大侠五级) | 2014-08-07 15:36

@519740105: 我们再来看你新给的这段代码中的这条语句: var type = @object.GetType();

请问,你需要这里的 type 变量用来做什么?

Launcher | 园豆:45050 (高人七级) | 2014-08-07 15:38

@Launcher: 这里只是一个例子,我只是问这里如何获取到类型 Nullable<int>。

519740105 | 园豆:5810 (大侠五级) | 2014-08-07 15:45

@519740105:你这个弯儿没转过来,还是看这里: http://msdn.microsoft.com/en-us/library/ms366789.aspx,这里已经说的很明白了,你用 i.GetType() 是获取不到同 Nullable<> 类型有关联的信息的。因此我才问你必须得到 Nullable<int> 类型来做什么,因为你的需求可以通过其它方式来实现。

Launcher | 园豆:45050 (高人七级) | 2014-08-07 16:07
其他回答(2)
0

试过用反射吗?

收获园豆:2
XiaoFaye | 园豆:3087 (老鸟四级) | 2014-08-07 09:49

简单的尝试了下,不可以达到目的,即便处理了,也将会很复杂了。 

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2014-08-07 10:34

@519740105: 

第一个应该是这样吧:

bool compatible = typeof(Nullable<int>).IsAssignableFrom(i.GetType());

这时候compatible 就是true了。

支持(0) 反对(0) XiaoFaye | 园豆:3087 (老鸟四级) | 2014-08-07 10:47

@XiaoFaye: 

第二个i.GetType()我在Watch里面看到是Int32类型的。

支持(0) 反对(0) XiaoFaye | 园豆:3087 (老鸟四级) | 2014-08-07 10:48

@XiaoFaye: 换成List<>也类似。

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2014-08-07 10:51

@XiaoFaye: 关键是:此时我只想判断是否派生自Nullable<>(或者兼容),而且,int类型在运行过程中是不知道的。

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2014-08-07 10:53

@519740105: 

你是说传过来给你的只是一个object,你要判断这个object是否派生自Nullable<>?

支持(0) 反对(0) XiaoFaye | 园豆:3087 (老鸟四级) | 2014-08-07 11:04

@XiaoFaye: 对。

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2014-08-07 11:20
0

他这样已经算是在用反射了```

你调试打断点,看typeof出来的类型信息里面就能看出来.

收获园豆:2
吴瑞祥 | 园豆:29449 (高人七级) | 2014-08-07 10:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册