【问题标题】:How to override a method in another assembly?如何覆盖另一个程序集中的方法?
【发布时间】:2010-10-14 09:12:54
【问题描述】:

我之前问过一个关于接口的问题,得到了一些很好的回答。我很高兴开始开发真正灵活的代码。

我现在有一个关于覆盖虚拟方法的问题。

我目前正在使用社区服务器 SDK。其中一个控件是“标记”面包屑。因此它将列出相关对象上的“标签”。

<CSBlog:TagBreadCrumb />

我正在使用标签来允许管理员定位特定位置以使内容出现在布局中,但是这些标签与最终用户无关。例如,“Home_Main”标签用于定位主页上的主面板,但我不希望用户看到。

由于我有社区服务器的 SDK,我找到了呈现“标签列表”的控件,并对其进行了修改以执行我想要的操作 - 但是我的理解是,出于多种原因修改核心并不好。

所以我想做的是创建自己的控件,它基本上与基本控件几乎 100% 相同,但覆盖了一种方法。

方法如下:

 public virtual string FormatTags(string[] tagList)

里面有格式化标签的代码,我想写我自己的代码来做所有相同的事情,除了检查配置文件中要排除的“标签”。

所以我的理解是我创建了我的控件,从基本控件派生 - 我可以编写自己的 FormatTags() 方法 - 对吗?

我只需要改变它的一个方面,但这是否意味着我必须从基类复制该方法的原始代码 - 并在那里改变我需要的东西?它只是从一个地方感觉不正确的复制代码,但我不知道在不更改基类中的代码的情况下扩展该方法的另一种方法。

感谢您的任何建议。

【问题讨论】:

    标签: c# asp.net community-server


    【解决方案1】:

    在您的情况下(您想禁止在面包屑中打印某些标签),您将在调用基本方法之前去除所有特殊标签。

    所以你的代码看起来像:

    public override string FormatTags(string[] tagList)
    {
      // strip special tags
      string[] newTagList = stripTags(tagList);
      return base.FormatTags(newTagList);
    }
    

    这样您就不需要了解基类如何格式化输出字符串。

    如果您想修改输出字符串的格式,则不会对基本方法进行任何调用(因为该方法可能会在未来版本中更改其格式,您不希望受到)。

    【讨论】:

    • 哇。看到这让灯泡熄灭了!!谢谢!
    【解决方案2】:

    您仍然可以运行派生方法并对其结果进行操作:

    public override string FormatTags(string[] tagList) {
        string result = base.FormatTags(tagList);
        // do something with result
        return result;
    }
    

    【讨论】:

    • 有趣! FormatTags 中发生的一件事是标签变成了链接——这让我更难解析它们,而不是不包括它们。我应该处理这个 - 还是在那时我复制基本代码并进行一些更改?谢谢。
    【解决方案3】:

    所以我的理解是我创建了我的控件,从基本控件派生 - 我可以编写自己的 FormatTags() 方法 - 对吗?

    没错;覆盖时,您提供自己的基类方法实现。

    在最好的情况下,会发生以下两种情况之一:

    • 有一种简单的方法可以将基类方法的输出转换为所需的结果。

    • 基类使用策略模式或其变体,因此您只需提供策略适当部分的替代实现。

    不幸的是,这听起来不像这里的任何一个,所以你可能不得不从头开始编写它。

    【讨论】:

      【解决方案4】:

      所以我的理解是我创造 我的控制,来自基础 控制 - 我可以自己写 FormatTags() 方法 - 正确吗?

      完全正确。

      如果您发现需要复制大量代码,您应该考虑重组您的方法。将要复制的代码放入您不会覆盖的另一个方法中,然后当您覆盖 FormatTags 时,更改您需要的内容并访问您将通过调用另一个方法复制的代码。

      【讨论】:

        【解决方案5】:

        看看extension methods。这些允许您通过在自己的静态类中定义函数来扩展无法编辑或扩展的密封类的功能。这是我刚刚写的一个例子(可能有语法错误)。

        public static class MyExtensions
        {
            public static string AppendCrazyText(this string s, string crazyText)
            {
                return s + crazyText;
            }
        }
        

        现在,要访问它,我只需调用:

        string myString = "Hello world";
        string myCrazyText = ", lets go crazy!";
        
        string myResult = myString.AppendCrazyText(myCrazyText);
        

        【讨论】:

          猜你喜欢
          • 2011-09-10
          • 2013-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多