什么场景下才需要使用“方法隐藏”? [复制]

2024-04-23

可能的重复:
隐藏在 C# 中的方法并带有有效示例。为什么它在框架中实现?现实世界的优势是什么? https://stackoverflow.com/questions/1193848/method-hiding-in-c-sharp-with-a-valid-example-why-is-it-implemented-in-the-fram

我想知道方法隐藏在 C# 中如何有用?如果你深入研究这个概念,你会发现方法隐藏是很重要的令人困惑的并驱使我们去意大利面条代码风格。有一些原因:

1-如果您需要在派生类中使用新方法,您可以在派生类中使用新名称定义新方法。

2-当您使用向上转换时,以多态方式使用,将无法实现预期的行为,这可能会令人困惑。

(特别是,如果基类和派生类位于不同的库中,并且您希望在代码中的某个位置对它们进行多态使用,则这种奇怪的行为可能会非常明显)

class Base
{  
    public void Method() { Console.WriteLine("I am Base Class"); }
}
class Derived: Base
{
    public new void Method() { Console.WriteLine("I am Derived Class");}
}
class Program
{
    static void Main(string[] args)
    {
        Base C = new Derived();
        C.Method(); //output:"I am Base Class"
    }
}

这种行为可能会令人困惑,但如果我们使用“virtual" in "Base" and "override" in "Derived“(我的意思是多态用法)输出是:“我是派生类”。 我认为这个输出是我们大多数人所期望的。

换句话说,我相信在层次结构中,大多数开发人员期望派生类中的重写方法而不是想要隐藏基类实现的新方法。

我不明白为什么c#语言中有这样一个没有优点的坏东西?至少我想知道 C# 中隐藏方法的最佳用法是什么?

感谢您的帮助


如果您需要在派生类中使用新方法,您可以在派生类中使用新名称定义新方法

不总是。考虑这样一种情况,您派生了一个在其他库中公开的类,而您无法控制该库。您向类中添加一些方法。

后来,您所依赖的库的开发人员添加了一些增强功能,并使用与您添加到派生类中的方法之一相同的名称。在这种情况下隐藏的只是保留现有的功能。如果更改方法名称,则必须更新整个代码库,并且会破坏与使用您的库的任何人的兼容性。相反,您可以隐藏现有方法并同时保留与依赖项和您依赖的库的兼容性。

就我个人而言,我最常使用方法隐藏的情况是在多个类上实现克隆操作时;如果没有此功能,我无法更改返回类型以匹配该类的返回类型:

class A
{
    public A Clone()
    {
        return CloneImpl();
    }

    protected virtual A CloneImpl()
    {
        return MemberwiseClone();
    }
}

class B : A
{
    new public B Clone()
    {
        return (B)CloneImpl();
    }
}

受保护的虚拟方法意味着无论是哪个Clone()当你调用时,你仍然会得到正确类型的对象。但是,您获得的引用类型将取决于您用于调用的引用类型Clone()。这允许:

B b = new B();
B b2 = b.Clone(); // Did not have to cast, thanks to the hiding method.

A a = b;
A a2 = a.Clone(); // Still returns a B, only typed as an A.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么场景下才需要使用“方法隐藏”? [复制] 的相关文章

  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 按成员序列化

    我已经实现了template
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • PHP 接口有属性吗?

    PHP 中的接口有属性 还是只有方法 您可以在 DocBlock 中为接口声明属性 然后 IDE 将提示接口的这些属性 PhpStorm 会这样做 但这不会强制在实现类中实际实现这些字段 例如 property string passwor
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 重载<<的返回值

    include
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐