2012-03-23 135 views
1

我想学习委托,不知道我做错了什么。所以我有三个类,Form1,Class1和Class2。 Form1调用Class1方法为Class1成员设置字符串,然后Form1启动workerbackground线程以启动Class2。但是,当Class2调用Form1委托方法将调用Class1方法来获取字符串数据,但它返回为Class2为null。C#委托返回NULL

因此,这是它返回null,>>字符串str = form1Obj.gDelegateClass1GetData(();

这是Form1中:

public delegate string DelegateClass1GetData(); 
public delegate void DelegateClass1SetData(string data); 

public partial class Form1 : Form 
{ 
    public DelegateClass1GetData gDelegateClass1GetData; 
    public DelegateClass1SetData gDelegateClass1SetData; 

    public Class1 class1Obj; 
    public BackgroundWorker bw_Class2; 
    public Class2 class2Obj; 


    public Form1() 
    { 
     InitializeComponent(); 

     class1Obj = new Class1(); 
     class2Obj = new Class2(this); 


     gDelegateClass1GetData = new DelegateClass1GetData(this.Class1GetData); 
     gDelegateClass1SetData = new DelegateClass1SetData(this.Class1SetData); 
    } 


    private void button1_Click(object sender, EventArgs e) 
    { 
     class1Obj.setClass1Data("Hello"); 

     bw_Class2 = new BackgroundWorker(); 
     bw_Class2.WorkerSupportsCancellation = true; 

     bw_Class2.DoWork += new DoWorkEventHandler(ThreadClass2_DoWork); 
     bw_Class2.RunWorkerAsync(); 
    } 


    public string Class1GetData() 
    { 
     if (InvokeRequired) 
      Invoke(new DelegateClass1GetData(Class1GetData)); 
     else 
     { 
      return class1Obj.GetClass1Data(); 
     } 

     return null; 
    } 


    public void Class1SetData(string data) 
    { 
     if (InvokeRequired) 
      Invoke(new DelegateClass1SetData(Class1SetData), data); 
     else 
     { 
      class1Obj.setClass1Data(data); 
     } 
    } 


    public void ThreadClass2_DoWork(object sender, DoWorkEventArgs e) 
    { 
     string str1 = class1Obj.GetClass1Data(); 
     class2Obj.AddString(); 
    } 

} 

这是1类:

public class Class1 
{ 
    public string gClass1Data; 

    public Class1() 
    { 
     gClass1Data = null; 
    } 


    public void setClass1Data(string data) 
    { 
     gClass1Data = data; 
    } 


    public string GetClass1Data() 
    { 
     return gClass1Data; 
    } 
} 

本类2:

public class Class2 
{ 

    public Form1 form1Obj; 

    public Class2(Form1 obj) 
    { 
     form1Obj = obj; 
    } 


    public void AddString() 
    { 
     string str = form1Obj.gDelegateClass1GetData(); 
     str = str + " Delegate"; 

     form1Obj.gDelegateClass1SetData(str); 
     string str2 = form1Obj.gDelegateClass1GetData(); 
    } 
} 
+0

你有没有尝试在form1.Class1GetData()中看到什么是断点?如果invoke是必需的,那么该方法将返回null。 – JamieB 2012-03-23 02:28:26

+0

是的我试着用断点调试它,它显示需要调用。不知道这意味着什么,但会读入它。谢谢。 – Lufia 2012-03-23 02:39:54

回答

2

问题在于Form1.Class1GetData方法。当您在Class2.AddString()中拨打form1Obj.gDelegateClass1GetData()时,实际上您会拨打Form1.Class1GetDataInvokeRequired返回true,您必须再次拨打Form1.Class1GetData。这一次,InvokeRequired返回false,你打电话class1Obj.GetClass1Data(),并返回“你好”。它实际上返回到第一个电话Form1.Class1GetData,但您最终返回null。所以,你得到nullstring str = form1Obj.gDelegateClass1GetData(();。尝试修复它作为

public string Class1GetData() 
{ 
    if (InvokeRequired) 
     return (string) Invoke(new DelegateClass1GetData(Class1GetData)); // return the first call to Class1GetData 
    else 
    { 
     return class1Obj.GetClass1Data(); 
    } 

    //return null; // Don't return null. 
} 
+0

感谢您一步一个脚印。但是,如果我删除返回null,我会得到错误,因为它不包括所有的返回路径。我也试图声明局部变量,以便返回Class1Ojb.GetClass1Data(),我把变量字符串名称= Class1Obj.GetClass1Data();然后在下面返回变量字符串名称,但仍为空。 – Lufia 2012-03-23 02:44:29

+1

@Lufia - 注意Invoke调用前面的'return(string)'。这是他指出的。在需要Invoke的情况下,它会调用,但会下降到您的'返回null'。这就是为什么你得到空值。 – Mufaka 2012-03-23 02:51:33

+0

哦哇!感谢您指出了这一点。我没有看到代码中的返回(字符串)。这是解决它,并感谢姚。 – Lufia 2012-03-23 02:58:34