在C#中是否可以交换方法的实现,比如Objective-C中的方法交换?
因此,我可以在运行时用自己的实现替换现有实现(通过dll等外部来源),或者在其上添加另一个。
我已经搜索过了,但没有找到有价值的信息。
在C#中是否可以交换方法的实现,比如Objective-C中的方法交换?
因此,我可以在运行时用自己的实现替换现有实现(通过dll等外部来源),或者在其上添加另一个。
我已经搜索过了,但没有找到有价值的信息。
delegates
,让您的代码在运行时指向任何您想要执行的方法。public delegate void SampleDelegate(string input);
void
,并以 string
为输入的方法。您可以将具有该签名的任何方法分配给它。这也可以在运行时完成。public delegate void SampleDelegate(string input);
...
//Method 1
public void InputStringToDB(string input)
{
//Input the string to DB
}
...
//Method 2
public void UploadStringToWeb(string input)
{
//Upload the string to the web.
}
...
//Delegate caller
public void DoSomething(string param1, string param2, SampleDelegate uploadFunction)
{
...
uploadFunction("some string");
}
...
//Method selection: (assumes that this is in the same class as Method1 and Method2.
if(inputToDb)
DoSomething("param1", "param2", this.InputStringToDB);
else
DoSomething("param1", "param2", this.UploadStringToWeb);
DoSomething("param1", "param2", (str) => {//在此处执行所需操作});
另一种选择是使用策略设计模式
。在这种情况下,您声明接口并使用它们来表示提供的行为。public interface IPrintable
{
public void Print();
}
public class PrintToConsole : IPrintable
{
public void Print()
{
//Print to console
}
}
public class PrintToPrinter : IPrintable
{
public void Print()
{
//Print to printer
}
}
public void DoSomething(IPrintable printer)
{
...
printer.Print();
}
...
if(printToConsole)
DoSomething(new PrintToConsole());
else
DoSomething(new PrintToPrinter());
Foo
类和bar
实现,然后交换该方法,这样每次调用bar
时,运行时实际上执行您的方法。这是一项运行时功能,不需要Foo
类的创建者做任何事情。 - JustSid虽然在 strongly-typed 语言中,这不是最好的面向对象编程方式,但需要提到的是,自从 .NET 4.0 开始,C# 已经包含了动态语言运行时 (DLR),可以实现动态编程。其中最引人注目的动态对象之一是 ExpandoObject
:一个完全可在运行时扩展的对象:
dynamic expando = new ExpandoObject();
expando.DoStuff = new Func<string>(() => "hello world");
// Now you can swap DoStuff with other method setting another delegate:
expando.DoStuff = new Func<string, string>(text => text + "!");
顺便说一下,正如我之前所说的,我在这里分享这种方法只是为了学习目的。它可能在某些边缘情况下有用,但由于C#是一种编译型和强类型语言,在99.99%的情况下应避免使用这种方法。
public void Foo()
{
Bar();
}
public void Bar()
{
}
那么你无法让Foo
调用除Bar
之外的任何其他方法。你在Objective-C中提到的方法分派表在.NET中是不可变的。
为了能够指定Foo
应该调用哪个方法,你需要使用一个delegate
:
public void Foo(Action whichMethod)
{
whichMethod();
}
你可以这样调用:
Foo(Bar);
Foo(Baz);
但是必须建立方法来允许这种运行时替换。
void Test(Action method) {
if ( method != null ) method.invoke();
}
你可以调用这个
Test( () => { Console.WriteLine("hello world"); } )
修改定义后再次调用
Test( () => { MessageBox.Show("Hi"); } )
Func
、Action
、delegate
、lambda
可以轻松模拟这个。 - Nikson Kanti PaulIoC / DI
模式,否则不需要。 - Nikson Kanti Paul