C#:可能没有在抽象类上实现受保护的内部抽象?

时间:2010-11-11 16:15:00

标签: c# abstract-class access-modifiers

我需要在抽象基础上进行哪些更改,以便在任何给定方案中只需要一个实现时,实现不必实现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;
    }
}

干杯。

编辑:设计很奇怪/糟糕/愚蠢我知道......我正在使用遗留代码,现在时间不适合我的重构。我正在尝试使用字符串数组添加第二个方法。

9 个答案:

答案 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)

你不能这样做。唯一的选择是重新安排你的课程。