2015-01-04 51 views
0

我努力理解代表和该委托我创建了一个简单的例子,为自己,但它不工作,我希望它的方式,这里是我的例如:如何通过两项功能,其他功能与在C#中的参数

我的功能:

class Functions 
{ 

    public string MyFname(string MyString) 
    { 

     return MyString; 


    } 
    public string MyLname(string MyString) 
    { 

     return MyString; 


    } 


} 

代表:

class DelClass 
{ 
    public delegate string StrDelegate(string OutPutString); 

    public void StringCon(StrDelegate Fname,StrDelegate Lname) 
    { 

     Console.WriteLine(Fname + " " + Lname); 

    } 
} 

主营:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DelClass MyDel = new DelClass(); 
     Functions MyTster = new Functions(); 
     DelClass.StrDelegate Name = new DelClass.StrDelegate(MyTster.MyFname); 
     Name("SomeVariableName"); 
     DelClass.StrDelegate Family = new DelClass.StrDelegate(MyTster.MyLname); 
     Family("SomeVariableFamilyName"); 
     MyDel.StringCon(Name, Family); 

    } 
} 

问题是控制台窗口不显示我传递的字符串,而不是它显示了下述文字:

MyDelegateMethodInMethod.DelClass + StrDelegate MyDelegateMethodInMethod.DelClass + StrDelegate

当我尝试像这样在StringCon体中调用传递函数:

Console.WriteLine(Fname() + " " + Lname(); 

编译器co说明“委托'StrDelegate'不接受0参数”,但我不想在StringCon的传递参数中传递参数,我想在我的主函数中这样做,甚至可以通过委托来实现吗?

+0

它怎么能起作用?在StringCon()中,FName和LName是委托(方法),但没有数据(字符串)可以操作。 – 2015-01-04 13:08:50

+1

我相信你的逻辑中的缺陷是调用一个委托会将委托设置为返回值。事实并非如此。当您调用委托时,它立即返回值。 – juharr 2015-01-04 13:14:21

回答

2

如果你不希望传递一个字符串作为输入,您应恰当地宣布代表:

class DelClass 
{ 
    public delegate string StrDelegate(); 
    public void StringCon(StrDelegate Fname,StrDelegate Lname) 
    { 
     Console.WriteLine(Fname() + " " + Lname()); 
    } 
} 

从你写的,你要保存在某个地方的字符串属性 - 但委托是不是地方做it.You可以创建FName参数,LName的属性的对象:

class Functions 
{ 
    public string MyFname() { return MyFnameProperty; } 
    public string MyLname() { return MyLnameProperty; } 
    public string MyFnameProperty { get; set; } 
    public string MyLnameProperty { get; set; } 
} 

最后,在主,你会写:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DelClass MyDel = new DelClass(); 
     Functions MyTster = new Functions(); 
     DelClass.StrDelegate Name = new DelClass.StrDelegate(MyTster.MyFname); 
     MyTster.MyFnameProperty ="SomeVariableName"; 
     DelClass.StrDelegate Family = new DelClass.StrDelegate(MyTster.MyLname); 
     MyTster.MyLnameProperty = "SomeVariableFamilyName"; 
     MyDel.StringCon(Name, Family); 
    } 
} 
+0

他明确提到这是行不通的 – Icepickle 2015-01-04 13:00:28

+0

Icepickle - 你是对的,我相应地纠正了。我一读就错过了。 – ShayD 2015-01-04 13:13:10

2

这是不是真的,你应该如何使用委托,代表们主要用作回调函数或事件处理,或当你想调用一个函数。

的事件处理程序的一个例子是

public delegate void ReportErrorDelegate(object sender, MyCustomEventArgs e); 

带班

public class MyCustomEventArgs : EventArgs 
{ 
    // some implementation 
    public MyCustomEventArgs() 
    { 
    } 

    public MyCustomEventArgs(object argument) 
     : this() 
    { 
     .... 
    } 
} 

事后你可以创建它是基于将委托作为

public interface IRaiseMyCustomEventArgs 
{ 
    event ReportErrorDelegate CustomEventFired; 
} 

的事件,你可以实现为

public class RaiseMyCustomEventArgs : IRaiseMyCustomEventArgs 
{ 
    public event ReportErrorDelegate CustomEventFired; 

    protected virtual void RaiseCustomEventArgs(object argument) 
    { 
     var local = CustomEventFired; 
     if (local != null) { 
      local.Invoke(this, new MyCustomEventArgs(argument)); 
     } 
    } 
} 

的另一种选择可能是你检测到一个UI交互需要被调用,像这样的

public delegate void SetTextDelegate(TextBox tb, string text); 

public void SetText(TextBox tb, string text) 
{ 
    if (tb.InvokeRequired) 
    { 
      tb.Invoke(new SetTextDelegate(SetText), tb, text); 
      return; 
    } 
    tb.Text = text; 
} 

会从Windows应用程序中运行的线程调用后调用一个方法(例如)

public void RunThread() 
{ 
    // assuming TextBox1 exists on the form 
    Thread t = new Thread(() => { 
     SetText(TextBox1, "Hello World"); 
    }); 
    t.Start(); 
} 
7

委托是包含对方法的引用的对象。调用委托具有执行该方法的效果。您的两种方法各有一个参数String,以便执行通过的那些方法中的任一个传递单个String参数。这意味着,当您调用委托时,他们需要将一个String参数传递给它们执行的方法。你认为价值将来自哪里?代表不会凭空取胜。您在调用它时必须将其传递给委托。在此代码中:

public void StringCon(StrDelegate Fname,StrDelegate Lname) 
{ 
    Console.WriteLine(Fname + " " + Lname); 
} 

你在做什么?你不是。你必须提供的参数来代表,以便为他们提供他们的方法:

public void StringCon(StrDelegate Fname,StrDelegate Lname) 
{ 
    Console.WriteLine(Fname("John") + " " + Lname("Doe")); 
} 

这是一个非常贫穷的示范,但因为你的方法不会做任何有用的事情。如何定义一个方法做这样的一些有用的东西:

public string GetFullName(string givenName, string familyName) 
{ 
    return givenName + " " + familyName; 
} 

和相应的委托:

public delegate string FullNameGetter(string givenName, string familyName); 

,然后调用它像这样:

var fng = new FullNameGetter(GetFullName); 

Console.WriteLine(fng("John", "Doe")); 
+0

Jmc,+1用于解释*委托是表示对具有特定参数列表和返回类型的方法的引用的类型。当您实例化委托时,可以将其实例与具有兼容签名和返回类型的任何方法相关联。您可以通过委托实例调用(或调用)该方法*(Microsoft doc)实际上意味着*委托是包含对方法的引用的对象。调用委托具有执行该方法的效果。* LOL我可以明白为什么人们无法理解代表。 – BobRodes 2015-01-04 14:53:26