C# 如何从使用Activator.CreateInstance创建的表单返回值

C# 如何从使用Activator.CreateInstance创建的表单返回值,c#,winforms,C#,Winforms,我需要从使用Activator.CreateInstance创建的表单中获取返回值,但是尽管返回值设置为公共变量,但我只在调用表单中获取错误。这是密码 private void zButtonInsert1_Click(object sender, EventArgs e) { var type = Type.GetType("MyNamespace." + this.form_name); using (var form = Activator.

我需要从使用
Activator.CreateInstance
创建的表单中获取返回值,但是尽管返回值设置为公共变量,但我只在调用表单中获取错误。这是密码

    private void zButtonInsert1_Click(object sender, EventArgs e)
    {
        var type = Type.GetType("MyNamespace." + this.form_name);
        using (var form = Activator.CreateInstance(type, UIB, ID) as Form)
        {
            if (form != null)
                form.ShowDialog();
                 this.ID = form._id; //Here I got the error
        }
    }
这是错误消息

“Form”不包含“\u id”的定义,并且找不到接受“Form”类型的第一个参数的扩展方法“\u id”(是否缺少using指令或程序集引用?)

在被调用的表单中,值(lastID)被分配给公共变量

  _id = (int)kon.lastID;

您应该使用get属性、字段。。。。像这样

var value = type.GetProperty("SomeProperty").GetValue(object)...;

实际上,您正在将实例类型转换为
表单
,默认情况下,该实例没有任何名为
\u id
的属性,因此会出现错误

您可以使用反射来获取属性

private object GetProperty(Form obj, string propName)
{
   var p = ob.GetType().GetProperty(propName);
   if(p != null)
   {
       return p.GetValue(ob);
   }
   return null;
}
然后你可以像下面那样调用你的代码-

if (form != null)
{
   form.ShowDialog();
   object val = GetProperty(form, "_id");
   this.ID = TypeCastValHere(val);
}

不要忘记将返回值从object类型强制转换为'this.ID'类型

最好使用类型化对象。但在这里,我假设您希望使用类型名称创建对象,但不希望/不能将对象强制转换为所需的类型

即使在这种情况下,因为您知道表单有一个
\u id
字段,所以您可以强制表单创建
id
属性,实际上强制表单实现一个接口,并在读取值时将其转换到接口

比如说

public interface IFormWithId
{
    int Id {get;set;}
} 
并为您的类实现接口:

public partial class SomeForm: IFormWithId
{
    public int Id {get;set;}    
    public SomeForm(int id)
    {
        InitializeComponent();
        Id = id;
    }
}
然后在读取值时,使用以下代码:

var id = ((IFormWithId)form).Id;

如果出于任何原因,你不想使用接口,你可以考虑以下选项:

如果
\u id
是私有或受保护字段

如果
\u id
是private或protected字段,并且表单没有公开该字段的属性,那么查找其值的唯一解决方案是使用reflecten。例如:

var field = form.GetType().GetField("_id", /*Use GetProperty for property*/
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance);
var value = field.GetValue(form);
如果
\u Id
是公共字段或属性

您可以通过以下方式使用
dynamic

var id = ((dynamic)form)._id;

表单
没有该字段或属性。你可能也需要使用反射来获得它。在这一点上,您似乎非常了解所需的表单类型,那么为什么不调用构造函数呢?表单确实具有该属性,并且它的值填充了正确的值,我在调试器中检查了该值。我来自Visual FoxPro,对C#还比较陌生,所以我不确定问题是什么?你的意思是为什么我不只是用
form frm=new form()
以通常的方式实例化表单?不,
form
没有-你可以。
Form
的子类可能会,但这不是您将对象强制转换到的对象。但是我会再次问,为什么您不只是调用例如
newmyform(UIB,ID)
?表单的内容是不同的,它可以根据提供的参数以几种方式运行。因此,我只设置了几个属性(表单名称、行为、Id、表、字段等),我已经完成了必须创建的任何新表单。欢迎:)在可以使用它们的情况下,不要忽略使用接口。他们将充当您的联系人。