C# 使用委托调用成员函数
C# calling member function with delegate
因为 this post 我创建了一个新问题以使我的问题更清楚。我有一个 class 和下一个 class 成员,所以会有一个 class 实例的菊花链。我的 class 中的函数调用链中的另一个成员函数或所有实例。
c++对这个问题有一个合理的解决方案。在 C# 中,我尝试了一个委托。我做了一个小程序来表达我的意思。
class Program {
static void Main(string[] args)
{
DaisyChain TestClass = new DaisyChain(1);
TestClass.AddClass(new DaisyChain(2));
TestClass.AllprintID();
}
}
class DaisyChain {
private int ClassID;
private DaisyChain NextClass;
public DaisyChain(int ID) {ClassID = ID; }
public void AddClass(DaisyChain newClass) {
if (NextClass == null) {
NextClass = newClass;
} else {
NextClass.AddClass(newClass);
}
}
public void AllprintID() {
DoForEach(this.printID);
}
public delegate void doFunc();
public void DoForEach (doFunc aMemberFunc) {
aMemberFunc();
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
public void printID() {
Console.WriteLine(ClassID);
}
};
这个例子不正确,因为 class 实例不是函数调用的一部分。
我可以向我的成员函数添加一个 class argumnet 并更改委托,
public void printID(DaisyChain me) {
Console.WriteLine(me.ClassID);
}
但此后函数将是静态的,无法再以正常方式使用。
如果有其他解决方案,我会很高兴。
委托类型应该有一个额外的参数,因为你想在不同的对象上调用printID
。您可以向 doFunc
添加一个,或者只使用内置的 Action<T>
委托类型。
public void DoForEach (Action<DaisyChain> aMemberFunc) {
aMemberFunc(this);
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
调用DoForEach
时,您可以传递一个lambda表达式:
public void AllprintID() {
DoForEach(x => x.printID());
}
或者如果你出于某种原因真的喜欢方法组语法,写一个本地函数printID
:
public void AllprintID() {
void PrintID(DaisyChain chain) {
chain.PrintID();
}
DoForEach(PrintID);
}
// method names should start with a capital letter :)
public void PrintID() {
Console.WriteLine(ClassID);
}
其他代码仍然可以像往常一样调用 PrintID
- AllprintID
之外的代码甚至不会注意到本地函数。
您正在尝试重新发明轮子。检查文档中的 LinkedList and LinkedListNode。这是一个让你上路的例子:
var daisyChain = new DaisyChain();
daisyChain.Add(1);
daisyChain.Add(2);
class DaisyChain: LinkedList<DaisyChainLink>
{
public void Add(int id) => AddLast(new LinkedListNode<DaisyChainLink>(new DaisyChainLink(id)));
public void Print()
{
var link = this.First;
link?.Value.Print();
while (null != link?.Next)
{
link = link.Next;
link?.Value.Print();
}
}
}
class DaisyChainLink
{
public DaisyChainLink(int id)
{
Id = id;
}
public int Id { get; }
public void Print() => Console.WriteLine(Id);
}
因为 this post 我创建了一个新问题以使我的问题更清楚。我有一个 class 和下一个 class 成员,所以会有一个 class 实例的菊花链。我的 class 中的函数调用链中的另一个成员函数或所有实例。
c++对这个问题有一个合理的解决方案。在 C# 中,我尝试了一个委托。我做了一个小程序来表达我的意思。
class Program {
static void Main(string[] args)
{
DaisyChain TestClass = new DaisyChain(1);
TestClass.AddClass(new DaisyChain(2));
TestClass.AllprintID();
}
}
class DaisyChain {
private int ClassID;
private DaisyChain NextClass;
public DaisyChain(int ID) {ClassID = ID; }
public void AddClass(DaisyChain newClass) {
if (NextClass == null) {
NextClass = newClass;
} else {
NextClass.AddClass(newClass);
}
}
public void AllprintID() {
DoForEach(this.printID);
}
public delegate void doFunc();
public void DoForEach (doFunc aMemberFunc) {
aMemberFunc();
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
public void printID() {
Console.WriteLine(ClassID);
}
};
这个例子不正确,因为 class 实例不是函数调用的一部分。
我可以向我的成员函数添加一个 class argumnet 并更改委托,
public void printID(DaisyChain me) {
Console.WriteLine(me.ClassID);
}
但此后函数将是静态的,无法再以正常方式使用。 如果有其他解决方案,我会很高兴。
委托类型应该有一个额外的参数,因为你想在不同的对象上调用printID
。您可以向 doFunc
添加一个,或者只使用内置的 Action<T>
委托类型。
public void DoForEach (Action<DaisyChain> aMemberFunc) {
aMemberFunc(this);
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
调用DoForEach
时,您可以传递一个lambda表达式:
public void AllprintID() {
DoForEach(x => x.printID());
}
或者如果你出于某种原因真的喜欢方法组语法,写一个本地函数printID
:
public void AllprintID() {
void PrintID(DaisyChain chain) {
chain.PrintID();
}
DoForEach(PrintID);
}
// method names should start with a capital letter :)
public void PrintID() {
Console.WriteLine(ClassID);
}
其他代码仍然可以像往常一样调用 PrintID
- AllprintID
之外的代码甚至不会注意到本地函数。
您正在尝试重新发明轮子。检查文档中的 LinkedList and LinkedListNode。这是一个让你上路的例子:
var daisyChain = new DaisyChain();
daisyChain.Add(1);
daisyChain.Add(2);
class DaisyChain: LinkedList<DaisyChainLink>
{
public void Add(int id) => AddLast(new LinkedListNode<DaisyChainLink>(new DaisyChainLink(id)));
public void Print()
{
var link = this.First;
link?.Value.Print();
while (null != link?.Next)
{
link = link.Next;
link?.Value.Print();
}
}
}
class DaisyChainLink
{
public DaisyChainLink(int id)
{
Id = id;
}
public int Id { get; }
public void Print() => Console.WriteLine(Id);
}