Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用类型变量强制转换_C#_Casting_Activator - Fatal编程技术网

C# 使用类型变量强制转换

C# 使用类型变量强制转换,c#,casting,activator,C#,Casting,Activator,下面的代码不起作用,我想知道如何将实例动态强制转换为运行时确定的类型 ChangeType()返回仍然需要强制转换的对象。调用GetConstructor()或Activator.CreateInstance()的所有尝试也是如此,请参见下文。在某个时候,我需要显式地强制转换代码,我希望尽量避免或将其推出 Type type = Type.GetType ("RandomChildClass"); Object obj = Activator.CreateInstance (type, new

下面的代码不起作用,我想知道如何将实例动态强制转换为运行时确定的类型

ChangeType()返回仍然需要强制转换的对象。调用GetConstructor()或Activator.CreateInstance()的所有尝试也是如此,请参见下文。在某个时候,我需要显式地强制转换代码,我希望尽量避免或将其推出

Type type = Type.GetType ("RandomChildClass");
Object obj = Activator.CreateInstance (type, new Object[]{ "argument" });
var instance = (type)obj;
我知道我可以创建一个方法来接受,但我仍然有同样的问题,即不知道如何使用动态随机类型调用它

将变量定义为
dynamic
,它应该可以工作,我的意思是您仍然不能强制转换它,但您可以访问您的方法:

dynamic obj = Activator.CreateInstance (type, new Object[]{ "argument" });
例如:

void AddToList(List<Control> list, string typeName) {
    var control = (Control)Activator.CreateInstance(typeName);
    list.Add(control);
}

不可能使用
类型
值来确定表达式的类型。(泛型类型参数与值不同,因为它们被编码到类型系统中。)

变量的值来自运行时代码执行,而表达式类型是编译时构造。不用说,编译发生在代码运行之前,因此不可能使用变量进行转换

Type type = Type.GetType ("RandomChildClass");
Object obj = Activator.CreateInstance (type, new Object[]{ "argument" });
var instance = (type)obj;
(albiet笨拙)或(基本上更容易使用反射)允许调用任意方法或访问针对通用对象类型表达式的属性/字段-这有时被称为“后期绑定”。但是,调用操作的表达式的类型仍然是object

可以用于统一不同的类实现,以实现正确的静态类型。然后,新创建的对象可以强制转换到所需的适用接口。与其他表达式一样,类型是编译时构造(因此必须直接指定接口),但代码现在不受特定类的限制


如果创建一个系统,使这些“动态类”直接用于静态类型(C#)代码,并且接口可以得到保证或限制在一个小集合内,那么使用接口可能是最干净的方法:例如
var myAction=(imyaaction)obj
。否则,请退回到动态访问-直接或在门面后面。

根据您的评论,您正试图将其添加到
列表中。我的第一个想法是,如果你不能静态地访问
某个动态类
,那么我很好奇你如何或者为什么会有一个
列表
。听起来,如果使用
List
List
来代替,代码会更好

如果您被限制为
列表
,那么听起来您应该直接跳到使用反射来调用
添加
方法

var listType = theList.GetType();
var method = listType.GetMethod("Add");
method.Invoke(theList, obj);

如果静态地知道基类的类型,则强制转换为该类型。例如:

void AddToList(List<Control> list, string typeName) {
    var control = (Control)Activator.CreateInstance(typeName);
    list.Add(control);
}
或使用OfType方法:

foreach (Button button in list.OfType<Button>())
    button.Click += Button_Click;

foreach (Label label in list.OfType<Label>())
    label.MouseOver += Label_MouseOver;
foreach(list.OfType()中的按钮)
按钮。单击+=按钮\u单击;
foreach(list.OfType()中的标签)
label.MouseOver+=label\u MouseOver;

您也可以使用反射,但这相当麻烦,因此我不会给出一个示例。如果在基类型的不同子类型上定义了具有相同名称的属性,但在基类型上没有定义,则反射将非常有用。如果有许多子类型,类型检查将变得很麻烦,因此反射可能是一种更好的方法。

在您强制转换后,您打算如何处理
实例
?只需将其添加到基本类型的列表中,而不使用dynamic?我得到了编译错误我希望动态地填充演员阵容中的“(IMYACTION)”部分,但是从你的解释来看,这根本不可能。对吗?@user2994682对。出于同样的原因,这是不可能的。@user2994682您可能会发现库()很有趣。对于混淆,我很抱歉,我只是想找到一种动态强制转换到特定子类的方法。如果我构造了一个子对象(通过调用构造函数)并将其转换为父对象,那么当我以后想要使用它时,我仍然需要显式地将其转换为子对象。但是如果我能够保留它的类型,将它添加到基类的列表中,在使用时它仍然保留它自己的类型(不是基类),我的假设是错误的吗?谢谢,我想尝试保留子类的类型。可能吗?@user2994682正如user2864740回答的那样,不,不可能在编译时保留子级的静态类型。但是,子对象始终保留其运行时。例如,此代码生成一个包含一个字符串和一个装箱int的列表:
var objects=newlist{“one”,2}
。这些对象将始终是一个字符串和一个装箱的int。如果在从列表中检索子对象后需要执行特定于子对象的类型,请测试该类型并强制转换(可能使用type
方法的Linq
),或者使用反射。我将添加几个示例。