【问题标题】:How to use local variable as a type? Compiler says "it is a variable but is used like a type"如何使用局部变量作为类型?编译器说“它是一个变量,但用作类型”
【发布时间】:2018-11-29 07:47:58
【问题描述】:

在运行时,我不知道v1 是什么类型的变量。 为此,我写了很多if else声明:

if (v1 is ShellProperty<int?>)
{
    v2 = (v1 as ShellProperty<int?>).Value;
}
else if (v1 is ShellProperty<uint?>)
{
    v2 = (v1 as ShellProperty<uint?>).Value;
}
else if (v1 is ShellProperty<string>)
{
    v2 = (v1 as ShellProperty<string>).Value;
}
else if (v1 is ShellProperty<object>)
{
    v2 = (v1 as ShellProperty<object>).Value;
}    

唯一的区别在于ShellProperty&lt;AnyType&gt;

因此,我决定使用反射在运行时获取属性类型,而不是使用大量 if else 语句来编写:

 Type t1 = v1.GetType().GetProperty("Value").PropertyType;
 dynamic v2 = (v1 as ShellProperty<t1>).Value;

这段代码获取v1PropertyType 并将其分配给局部变量t1,但在那之后,我的编译器会这样说:

t1 是一个变量,但用作类型

所以它不允许我在ShellProperty&lt;&gt; 中写t1

请告诉我如何解决这个问题以及如何获得比我现有的更紧凑的代码。我需要创建一个新班级吗?

【问题讨论】:

  • 您不能以这种方式使用泛型。泛型在编译时是强类型的。
  • 所以你的意思是不可能的
  • 静态不是这样的。但你已经在做动态了。
  • 不使用动态对象。如果您的值是一个对象(即继承自 System.Object 或更好的是您拥有的某个基类),您可以使用object v2 = v1 as ShellProperty&lt;t1&gt;。 (同样,使用你自己的基类——或者更好的接口——会使它更有用。)

标签: c# reflection


【解决方案1】:

你非常接近,你只是错过了对MakeGenericType的呼叫。

我相信您的代码如下所示:

Type t1 = v1.GetType().GetProperty("Value").PropertyType;
var shellPropertyType = typeof(ShellProperty<>);
var specificShellPropertyType = shellPropertyType.MakeGenericType(t1);
dynamic v2 = specificShellPropertyType.GetProperty("Value").GetValue(v1, null);

编辑: 正如@PetSerAl 指出的那样,我添加了一些不必要的间接层。对不起,OP,你可能想要一个像这样的衬里:

dynamic v2 = v1.GetType().GetProperty("Value").GetValue(v1, null);

【讨论】:

  • 那是:v1.GetType().GetProperty("Value").GetValue(v1, null) 还不够吗?
  • @PetSerAl 你说的很对,我觉得很傻。我花了太多时间查看原始代码而没有足够的时间思考我的答案。我马上更新。
  • 非常有趣!也许@PetSerAl 是对的!但无论如何,这是为了“如何使用局部变量作为类型?”
  • 我相信这不是针对“如何使用局部变量作为类型?”的问题。当我得到同样的错误...
【解决方案2】:

对于泛型,您必须动态创建它们。

MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);

要创建通用对象,您可以

var type = typeof(ShellProperty<>).MakeGenericType(typeof(SomeObject));
var v2 = Activator.CreateInstance(type);

请参考Initializing a Generic variable from a C# Type Variable

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2016-10-17
    • 2014-05-28
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多