我需要在抽象基础上进行哪些更改,以便在任何给定方案中只需要一个实现时,实现不必实现BOTH方法?我的例子是:
internal abstract class BaseBar<T> where T : BaseThing
{
protected internal abstract T DataFromXmlElements(IEnumerable<XmlNode> nodes);
protected internal abstract T DataFromXmlElements(IEnumerable<XmlNode> nodes, string[] fieldNames);
}
class FooBarMapper : BaseBar<FooData>
{
protected internal override SforceObjectValueData DataObjectFromXmlElements(IEnumerable<XmlNode> nodes)
{
throw new NotImplementedException();
}
protected internal override FooData DataFromXmlElements(IEnumerable<XmlNode> nodes, string[] fieldNames)
{
FooData o = new FooData
{
bar1 = bar1,
bar2 = bar2
};
return o;
}
}
干杯。
编辑:设计很奇怪/糟糕/愚蠢我知道......我正在使用遗留代码,现在时间不适合我的重构。我正在尝试使用字符串数组添加第二个方法。
答案 0 :(得分:3)
也许这适合你?
internal abstract class BaseBar<T> where T : BaseThing
{
protected internal abstract T DataFromXmlElements(IEnumerable<XmlNode> nodes, params string[] fieldNames);
}
答案 1 :(得分:2)
您还可以在类中封装DataFromXmlElements的参数,然后在编写实现时以优雅的方式检查类的内容......
答案 2 :(得分:1)
我猜你需要2到3个抽象类才能实现这个目标
public interface BaseBar1<T> // does one
public interface BaseBar2<T> // does the other
public interface BaseBar3<T> // does both
您可以使用Optional参数
internal abstract class BaseBar<T> where T : BaseThing
{
protected internal abstract T DataFromXmlElements(
IEnumerable<XmlNode> nodes, string[] fieldNames);
}
class FooBarMapper : BaseBar<FooData>
{
protected internal override FooData DataFromXmlElements(
IEnumerable<XmlNode> nodes,
[Optional] string[] fieldNames)
{
if (fieldNames == null) // skip stuff
else // do stuff
}
有关Optional Attribute的更多信息。
答案 3 :(得分:1)
你可以创建一个或两个虚拟的,并提供默认实现,使用默认参数调用另一个(或不传递值,具体取决于你放置它的方式)。
但是,我怀疑你的设计可能真的需要更多的重新思考,因为调用者可能会引用基类(你的抽象类)并且不知道他们正在调用特定的派生版本,在这种情况下调用代码应始终可以随意调用它喜欢的方法。
答案 4 :(得分:1)
必须实现一个抽象成员,所以我想没有办法解决。
另一种解决方案是定义两个接口,每个接口包含一个要实现的成员。然后,实现类可以实现一个或两个接口。
例如:
public interface BaseBarA<T> where T : BaseThing{
protected internal abstract T DataFromXmlElements(IEnumerable<XmlNode> nodes);
}
public interface BaseBarB<T> where T : BaseThing{
T DataFromXmlElements(IEnumerable<XmlNode> nodes, string[] fieldNames);
}
答案 5 :(得分:1)
确切地说,你真正想要做的事情并不是很清楚。如果第一个方法被调用,你会发生什么?根据您的期望,您可以使父抽象类基于第二个方法的实现而实现第一个方法:
protected internal T DataFromXmlElements(IEnumerable<XmlNode> nodes) {
return DataFromXmlElements(nodes, null);
}
答案 6 :(得分:1)
不可能。
然而,您可以拥有一个抽象的内部基类,然后从中派生出两个抽象类(每个抽象方法都有一个抽象方法)。
最后,您将从抽象类的EITHER派生工作类,从而实现相应的单个方法。
“会”会起作用,但更大的问题是“你应该”吗? 我想你可能想重新考虑你的实施。
答案 7 :(得分:1)
像Colin Mackay所说的虚拟默认实现,或使用接口和显式实现来阻止外部调用方法。
internal interface IBaseBar1<T> where T : BaseThing
{
T DataFromXmlElements(IEnumerable<XmlNode> nodes);
}
interface IBaseBar2<T> where T : BaseThing
{
T DataFromXmlElements(IEnumerable<XmlNode> nodes, string[] fieldNames);
}
class FooBarMapper : IBaseBar2<FooData>
{
FooData IBaseBar2<FooData>.DataFromXmlElements(IEnumerable<XmlNode> nodes, string[] fieldNames)
{
FooData o = new FooData
{
bar1 = bar1,
bar2 = bar2
};
return o;
}
}
答案 8 :(得分:0)
你不能这样做。唯一的选择是重新安排你的课程。