C#语言:如何获取约束,但开放式泛型类的类型? [英] C# Language: How to get type of bound but open Generic class?

查看:166
本文介绍了C#语言:如何获取约束,但开放式泛型类的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有这样一个泛型类

Let's say I have such a generic class

public class XClass<T, U>
{
    public void MethodA<V>(){}
}

我怎么能得到

XClass<int,>



不是硬编码,并不限制如下MakeGenericType方法。

not hard-coded, not limiting to MakeGenericType method as below.

------用下面详述MakeGenericType阐述------

------ detailed elaboration below using MakeGenericType ------

我可以获得绑定和开放类的类型XClass<,>,其开放式的方法:

I can get the type of the unbound and open class "XClass<,>" and its open method:

var type = typeof(XClass<,>);
    Console.WriteLine(String.Format("Type ZClass<,>: \t generic? {0} \t open? {1}"
            , type.IsGenericType, type.IsGenericTypeDefinition));
var method = type.GetMethod("MethodA");
    Console.WriteLine(String.Format("Method MethodA<>: \t generic? {0} \t open? {1}"
            , method.IsGenericMethod, method.IsGenericMethodDefinition));



另外,我可以拿到全封闭班

Also, I can get the type of full closed class

XClass <int, char>

和它的关闭方法:

var type = typeof(XClass<,>); 
var method = type.GetMethod("MethodA"); 
var fullType = method.DeclaringType.MakeGenericType(new[]{typeof(int), typeof(char)});
    Console.WriteLine(String.Format("Type ZClass<int,char>: \t generic? {0} \t open? {1}"
            , fullType.IsGenericType, fullType.IsGenericTypeDefinition));
var fullTypeOpenMethod = fullType.GetMethod("MethodA");
var fullMethod = fullTypeOpenMethod.MakeGenericMethod(typeof(string));
    Console.WriteLine(String.Format("Method MethodA<String>:\t generic? {0} \t open? {1}"
            , fullMethod.IsGenericMethod, fullMethod.IsGenericMethodDefinition));

现在,我怎样才能得到约束,但公开课的类型

Now, How can I get the type of bound but open class

XClass<int, >

和它的方法是什么?

var type = typeof(XClass<,>); 
var method = type.GetMethod("MethodA");
Type [] types = new Type[2];
types[0] = typeof(int);
types[1] = null; // what shall i put here?
var halffullType = method.DeclaringType.MakeGenericType(types);

如果我把各类[1]为空,ArgumentNullException异常会抛出值不能为空

If I put types[1] as null, an ArgumentNullException exception will throw "Value cannot be null".

我应该怎么办?

推荐答案

你所提议做是不可能的,也不会真正帮助你。

What you are proposing to do is impossible and also will not really help you.

文档国家(重点煤矿)的

类型可以是开放的,就是有些$ b $乙的类型参数可以封闭泛型
方法或类型

Types constructed with MakeGenericType can be open, that is, some of their type arguments can be type parameters of enclosing generic methods or types.

这意味着,你不能让一个键入较对象 XClass< INT,> 。您的什么的可以做的是:

This means that you cannot make a Type object representing XClass<int,>. What you can do is:

class Outer<TOuter>
{
    class XClass<T, U> {}
}

在这种情况下,你可以做一个类型较对象外下 - ; TOuter> .XClass< INT,TOuter> 。但需要有一个封闭泛型类。

In this situation, you can make a Type object representing Outer<TOuter>.XClass<int, TOuter>. But there needs to be an enclosing generic class.

该文件还规定(指类似的例子以上)认为:

The documentation also states (referring to a similar example to the above) that:

一个构造类型,如基地发射代码时是非常有用的,
但你不能调用这种类型的MakeGenericType方法,因为它
不是泛型类型定义。要创建一个封闭构造类型
可以被实例化,首先调用GetGenericTypeDefinition
方法来获取表示泛型类型定义
Type对象,然后调用MakeGenericType与所需的类型参数。

A constructed type such as Base is useful when emitting code, but you cannot call the MakeGenericType method on this type because it is not a generic type definition. To create a closed constructed type that can be instantiated, first call the GetGenericTypeDefinition method to get a Type object representing the generic type definition and then call MakeGenericType with the desired type arguments.

这意味着,如果你有

Type myType = ... // represents Outer<TOuter>.XClass<int, TOuter>



然后得到一个键入 XClass< INT,串> 你首先需要调用 myType.GetGenericTypeDefinition()(从而失去了 INT 信息),然后调用 MakeGenericType 来把它放回(与字符串类型参数)。所以,它就像上一步,而前进两步。

Then to get a Type for XClass<int, string> you would first need to call myType.GetGenericTypeDefinition() (thus losing the int information) and then call MakeGenericType to put it back in (along with the string type parameter). So it's like one step back and two steps forward.

您可能要考虑存储的类型在一个单独的数据结构的参数类型 XClass (如键入[] ),只要不是所有的类型参数是众所周知的你,然后一气呵成创建封闭式泛型类型,你收集了所有的人之后。

You might want to consider storing the type parameter types for XClass in a separate data structure (e.g. a Type[]) for as long as not all type parameters are known to you, and then create the closed generic type in one go after you have collected all of them.

您也可以打包这一切都变成了一个小的辅助类方便:

You can also package all this into a small helper class for convenience:

class GenericTypeDescription
{
    private readonly Type openGenericType;
    private readonly Type[] typeParameters;

    public GenericTypeDescription(Type openGenericType)
    {
        // add checks for openGenericType actually being what it says here
        this.openGenericType = openGenericType;
        this.typeParameters = new Type[openGenericType.GetGenericArguments().Length];
    }

    public void SetTypeParameter(int index, Type type) {
        // add error handling to taste
        this.typeParameters[index] = type;
    }

    public Type ConstructGenericType() {
        // add error handling to taste
        return this.openGenericType.MakeGenericType(this.typeParameters);
    }
}

这篇关于C#语言:如何获取约束,但开放式泛型类的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆