下面是一段示例代码,im试图将var类型的变量作为引用参数发送给另一个函数。
Type type = Type.GetType(te1.GetValue("class1"));
MethodInfo method = type.GetMethod("fnc1");
var obj1 = Activator.CreateInstance(type);
我不能使用(class1)Activator.CreateInstance(type),因为变量class1将在运行时决定。这就是为什么我在这里使用反射。
method.Invoke(obj1, new object[] { });
class2 cls2= new class2 ();
cls2.fnc2(ref obj1);//getting error 'cannot convert object to class type'
当fnc2函数接收class1类型的参数时,Im出现错误。
public string fnc2(ref class1 obj3)
{
}
我该怎么处理?我需要使用反射将参数作为class1的类型获取。所以我使用了var类型。我不能使用dynamic,因为我使用的是framework 3.5。
我的要求是创建一个class1的对象>>执行class1的函数>>保留该对象并将该对象传递给class2的另一个函数并在那里进行处理。此外,class1和class2的名称将动态决定,不能硬编码。
var
不是类型。相反,它告诉编译器"自动确定类型"(并保存类型)。将鼠标悬停在下一行的obj1
上,Visual Studio将弹出一个方便的小框,说明实际类型被解析为什么,因为错误消息表明这是Object。
(在问题更新后,以下一些内容可能已经过时,但同样的原则也适用——表达式必须转换为适当的类型,这必须在编译时确定,然后才能用作Object之外的任何内容。)
"解决方案"只是投射Activator结果的结果(因为我们知道是这种情况):
var obj1 = (class1)Activator.CreateInstance(type);
// same as: class1 obj1 = (class1)..
然而,既然我们知道这一点,那么我们就可以避免所有这些,并使用以下内容,这很无聊:
var obj1 = new class1();
// same as: class1 obj1 = new class1();
因此,现在来讨论Y问题:对于任意类型,这是不可能的,并且需要强制转换。编译器已知的类型(可以在代码中使用)必须在编译时已知;它们不能直接从运行时值中解析。
如果您确定obj1
的类型与fnc2
所期望的类型相同,那么您可以使用这样的反射:
Type type = Type.GetType(te1.GetValue("class1"));
MethodInfo method = type.GetMethod("fnc1");
object obj1 = Activator.CreateInstance(type);
method.Invoke(obj1, new object[] {});
class2 cls2 = new class2();
cls2.GetType().GetMethod("fnc2").Invoke(cls2, new[] {obj1});
这将检索名为fnc2
的方法(假设只有一个具有该名称,没有重载),并使用obj1
调用它。如果存在重载,则需要此GetMethod变体。
顺便说一句,在这种情况下使用var并没有那么有用。为了清楚起见,我认为您应该只使用object
。