【发布时间】:2011-07-14 04:50:21
【问题描述】:
谁能告诉我是否有任何其他方式可以在不使用 C#/.NET 中的虚拟/抽象/覆盖的情况下覆盖方法,请提供一个示例。请提供一个示例... (我在想的是扩展方法,我是否正确.....)
【问题讨论】:
-
到目前为止你已经尝试过什么先生。你先尝试谷歌搜索吗?
-
是我自己还是这听起来很像作业/测试问题?
谁能告诉我是否有任何其他方式可以在不使用 C#/.NET 中的虚拟/抽象/覆盖的情况下覆盖方法,请提供一个示例。请提供一个示例... (我在想的是扩展方法,我是否正确.....)
【问题讨论】:
不,没有其他办法。如果基本方法未标记为virtual,您可以隐藏使用new 的现有方法,但是它没有相同的效果(没有多态性 - 调用将根据变量类型,而不是实际对象类型)。
【讨论】:
在这种情况下,扩展将不起作用。对象自己的属性和方法优先。但是,您可以使用扩展重载方法。
您可以覆盖扩展中定义的方法,方法是让您的扩展在命名空间中更靠近您将要使用它的位置。
例子:
namespace ConsoleApplication2
{
using System;
using ConsoleApplication3;
internal class Program
{
private static void Main(string[] args)
{
ThirdPartyClass t = new ThirdPartyClass();
Console.WriteLine(t.Fun("hh"));
Console.WriteLine(t.Fun(1));
}
}
public static class LocalExtension
{
public static string Fun(this ThirdPartyClass test, int val)
{
return "Local" + val;
}
public static string Fun(this ThirdPartyClass test, string val)
{
return "Local" + val;
}
}
}
namespace ConsoleApplication3
{
public class ThirdPartyClass
{
public virtual string Fun(string val)
{
return "ThirdParty" + val.ToUpper();
}
}
public static class ThripartyExtension
{
public static string Fun(this ThirdPartyClass test, int val)
{
return "ThirdParty" + val;
}
}
}
【讨论】:
您可以在方法上使用“new”关键字来“隐藏”未声明为抽象/虚拟的方法,但是如果从类型转换为基类的变量调用该方法,则不会调用你的新方法。这类似于覆盖。
例子:
public class A
{
public string GetName() { return "A"; }
}
public class B : A
{
// this method overrides the original
public new string GetName() { return "B"; }
}
扩展方法允许您向任何类添加新方法,即使您没有它们的源代码或它们是密封的。这与覆盖不同
public sealed class A // this could even be from a dll that you don't have source code to
{
}
public static class AExtensionMethods
{
// when AdditionalMethod gets called, it's as if it's from inside the class, and it
// has a reference to the object it was called from. However, you can't access
// private/protected fields.
public static string AdditionalMethod(this A instance)
{
return "asdf";
}
}
另一种选择是使用接口,这样您就可以拥有两个完全不同的对象,它们都具有相同的方法,但是当从类型转换为接口的变量调用时,它看起来类似于覆盖。
你也可以使用类似 Microsoft Moles 或 CastleWindsor 的代理模拟框架形式 -> 他们有一种方法可以实例化一个“代理”对象,该对象具有与真实对象相同的接口,但可以为每个对象提供不同的实现方法。
【讨论】: