1

有一个接口OptionsSet和一个抽象类StringBasedOptionsSet

interface OptionsSet {

    string getString(string key);

    int getInt(string key);

}

abstract class StringBasedOptionsSet : OptionsSet {

    int getInt(string key) {
        string v = getString(key);
        try {
            return Convert.ToInt32(v);
        }
        catch (Exception exc) {
            if (exc is FormatException || exc is OverflowException) {
                return 0;
            }
            throw;
        }
    }

}

为什么我不能调用getString(string)方法 from StringBasedOptionSet.getInt(string)

csmade/StringBasedOptionsSet.cs(21,36): error CS0103: The name `getString' does not exist in the current context
csmade/StringBasedOptionsSet.cs(32,25): error CS0103: The name `getString' does not exist in the current context

我也尝试过调用OptionsSet.getString(key)base.getString(key)这导致非静态方法/对象不包含 getString错误的定义。

编辑:在剥离示例时,StringBasedOptionsSet没有实现接口是一个错误。OptionsSet确实在我的实际代码中实现了接口。

4

3 回答 3

1

因为 StringBasedOptionsSet 没有实现接口,所以你的类应该是:

interface OptionsSet {

    string getString(string key);

    int getInt(string key);

}

abstract class StringBasedOptionsSet : OptionsSet {

    int getInt(string key) {
        string v = getString(key);
        try {
            return Convert.ToInt32(v);
        }
        catch (Exception exc) {
            if (exc is FormatException || exc is OverflowException) {
                return 0;
            }
            throw;
        }
    }

}

您可能还需要在抽象类中再次定义该函数。

于 2013-10-04T13:15:35.527 回答
1

您需要在抽象类定义中提供该方法作为abstract存根或适当的方法(可选):virtual

public abstract string getString(string key);

或者:

public virtual string getString(string key)
{
    return null;
}

这是模板方法模式

如果您打算强制派生类型提供getString,则需要一个abstract方法。如果您不想强制它,但允许它被覆盖,则需要默认virtual方法。

请注意,您的抽象类不需要直接实现接口,这可以在派生类中完成,只要方法定义正确,接口仍然可以满足:

interface IFoo
{
    string GetFoo();
}

abstract class FooBase
{
    public virtual string GetFoo()
    {
        return "Adam";
    }
}

class Foo : FooBase, IFoo
{
}

但是,您可能无论如何都不想这样做,这种设计似乎有点荒谬。

此外,C# 命名约定支持方法名称的标题大小写,因此GetIntGetString. 接口的命名约定是以I:为前缀IOptionSet

于 2013-10-04T13:13:30.597 回答
0

嗯,您的抽象类应该实现接口(因为它似乎是它的具体基础实现)并按照 Adam 的建议将 getString() 实现为抽象方法。

结果将是

abstract class StringBasedOptionsSet : OptionsSet
{
    public abstract string getString(string key);

    public int getInt(string key) 
    {
        string v = getString(key);
        try {
            return Convert.ToInt32(v);
        }
        catch (Exception exc) {
            if (exc is FormatException || exc is OverflowException) {
                return 0;
            }
            throw;
        }
    }
}
于 2013-10-04T13:24:11.933 回答