在c#中通过反射调用方法时无法更改标签文本

时间:2016-12-08 09:15:46

标签: c# .net reflection

首先查看我的代码

namespace HealthClub
{
    public partial class frmTrainerMaster : Form
    {
        DataTable dt = new DataTable();
        frmHome Home = new frmHome();
        public frmTrainerMaster()
        {
            InitializeComponent();            
        }
    }

    private void frmTrainerMaster_Load(object sender, EventArgs e)
        {            
            FillValues("UserNameText");            
        }


   public void FillValues(string UserName)
    {
        DataTable DT;
        SqlCommand cmd = new SqlCommand();
        try
        {
            cmd.Connection = Connections.Connection[UserName];
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "TrainerMaster_pro";
            cmd.Parameters.AddWithValue("Option", "FillValues".Trim());
            if (Connections.Connection[UserName].State == ConnectionState.Closed)
                Connections.Connection[UserName].Open();
            SqlDataAdapter adp = new SqlDataAdapter(cmd);
            DT = new DataTable();
            adp.Fill(DT);
            lblId___.Text = DT.Rows[0][0].ToString();                
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
        finally
        {
            cmd.Parameters.Clear();
            cmd.Dispose();
            Connections.Connection[UserName].Close();                
        }
    }
}

现在我从另一个类这样调用FillValues()

class AnotherClass
{
public void TestMethod(string FormName)
{
    Type tp = Type.GetType("HealthClub." + FormName);
                object myobj = Activator.CreateInstance(tp);
                MethodInfo method = myobj.GetType().GetMethod("FillValues");
                object[] parametersArray = new object[] { UserName };
                method.Invoke(myobj, parametersArray);    
}
}

如果查看FillValues(),我将数据库值分配给标签。当我在页面加载第一堂课时,它正常工作。

但是当我从第二个类调用方法时,Method会调用但数据库值不会分配给标签。

我需要做多少努力?

1 个答案:

答案 0 :(得分:0)

有一个类,有一个实例。这是您需要理解的非常基本的概念(不仅仅是在C#中,而是在任何面向目标的语言中)。

// class example
class FrmTrainerMaster  { public int SomeProperty { get; set;} }

创建新实例时:

// creates one window
var frmTrainerMasterInstanceOne = new FrmTrainerMaster();
frmTrainerMasterInstanceOne.SomeProperty = 1; 

// creates second window
var frmTrainerMasterInstanceTwo = new FrmTrainerMaster();
frmTrainerMasterInstanceTwo.SomeProperty = 2;

实例是独立的 - 所以此时查询

// will return 1 
Console.Out.WriteLine(frmTrainerMasterInstanceOne.SomeProperty);
// will return 2 
Console.Out.WriteLine(frmTrainerMasterInstanceTwo.SomeProperty);

反射var myobj = Type.GetType("HealthClub.FrmTrainerMaster");等于var myobj = new FrmTrainerMaster();所以通过myobj执行任何操作,您仍然无法影响frmTrainerMasterInstanceOnefrmTrainerMasterInstanceTwo

你需要的是实际的方法如何将实例(FrmTrainerMaster类)的引用传递到你需要的位置(让我们称之为AnotherForm),没有所有实例的魔术列表对于给定的类,除非你明确地构建它。

public partial class FrmTrainerMaster : Form
{
  public void FillValues(string userName) { ... }
}

一种方法是通过构造函数注入(通常提供 - 因为在构造对象(AnotherForm)时,你使它处于有效状态(即初始化所有依赖项)。

public class AnotherForm : Form {
   private readonly FrmTrainMaster _frmTrainMaster;
   public AnotherForm(FrmTrainMaster frmTrainMaster) {
     if (frmTrainMaster == null) {
       throw new ArgumentNullException(nameof(frmTrainMaster));
     }
     _frmTrainMaster = frmTrainMaster;
   }
}

或通过二传手注射:

public class AnotherForm : Form {
  private FrmTrainMaster _frmTrainMaster;
  public FrmTrainMaster MasterForm { set { _frmTrainMaster = value; } }
}

无论哪种方式,根本不需要反射。在您AnotherForm的任何地方,您都可以致电

class AnotherForm : Form {
  ...
  public void FooMethodThatCallFillValues() {
    _frmTrainMaster.FillValues("...");
  }
}