之前我问了一个关于接口的问题并得到了一些很好的回答。我很高兴能够开始开发真正灵活的代码。
我现在有一个关于覆盖虚拟方法的问题。
我目前正在使用社区服务器SDK。其中一个控件是“标签”面包屑。所以它会在相关对象上列出'标签'。
<CSBlog:TagBreadCrumb />
我正在使用标记来允许管理员定位特定位置以便在布局中显示内容,但这些标记与最终用户无关。例如,'Home_Main'标签用于定位主页上的主面板,但我不希望用户看到它。
由于我拥有社区服务器SDK,我发现了一个控件,它呈现了'标签列表'并对其做了我想要的修改 - 但我的理解是,由于很多原因修改核心并不好。
所以我想要做的是创建我自己的控件,它基本上与基本控件几乎完全相同,但是覆盖一个方法。
以下是方法:
public virtual string FormatTags(string[] tagList)
里面有代码来格式化标签,我想编写自己的代码来执行所有相同的操作,除了检查配置文件中是否要排除“标签”。
所以我的理解是我创建了我的控件,从基本控件派生 - 我可以编写自己的FormatTags()方法 - 这是正确的吗?
我只需要更改它的一个方面,但这是否意味着我必须从基类复制该方法的原始代码 - 并在那里更改我需要的内容?它只是从一个地方感觉不正确的copyign代码,但我不知道扩展方法的另一种方法而不改变基类中的代码。
感谢您的任何建议。
答案 0 :(得分:5)
在您的情况下(您希望禁止在面包屑中打印某些标记),您将在调用基本方法之前删除所有特殊标记。
所以你的代码看起来像:
public override string FormatTags(string[] tagList)
{
// strip special tags
string[] newTagList = stripTags(tagList);
return base.FormatTags(newTagList);
}
这样您就不需要了解基类如何格式化输出字符串。
如果您想要修改输出字符串的格式,则不会对基本方法进行任何调用(因为该方法可能会在将来的版本中更改它的格式,您不希望受其影响)。
答案 1 :(得分:4)
您仍然可以运行派生方法并对其结果进行操作:
public override string FormatTags(string[] tagList) {
string result = base.FormatTags(tagList);
// do something with result
return result;
}
答案 2 :(得分:1)
所以我的理解是我创建了我的控件,从基本控件派生 - 我可以编写自己的FormatTags()方法 - 这是正确的吗?
这是对的;当你覆盖时,你提供自己的基类实现方法。
在最好的情况下,会发生以下两种情况之一:
有一种简单的方法可以将基类方法的输出转换为所需的结果。
基类使用策略模式或其变体,因此您只需提供策略的适当部分的替代实现。
不幸的是,这听起来不像是这两种情况,因此您可能需要从头开始编写。
答案 3 :(得分:1)
所以我的理解是我创造了 我的控制,来自基地 控制 - 我可以写自己的 FormatTags()方法 - 是正确的吗?
绝对正确。
如果您发现需要复制大量代码,则应该考虑重构方法。将正在复制的代码放入另一个不会覆盖的方法中,然后当您覆盖FormatTags时,更改您需要的内容,只需通过调用其他方法访问您将复制的代码。
答案 4 :(得分:1)
看看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);