C#在抽象接口实现中调用未实现的方法

C#在抽象接口实现中调用未实现的方法,c#,interface,abstract-class,C#,Interface,Abstract Class,有一个接口optionset和一个抽象类StringBasedOptionsSet interface OptionsSet { string getString(string key); int getInt(string key); } abstract class StringBasedOptionsSet : OptionsSet { int getInt(string key) { string v = getString(key);

有一个接口
optionset
和一个抽象类
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;
        }
    }

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

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


编辑:剥离示例时,
stringbasedoptionset
未实现
选项集
界面是一个错误。它确实在我的实际代码中实现了接口。

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

public abstract string getString(string key);
或:

这是最新的

如果您打算强制派生类型提供
getString
,则需要
abstract
方法。如果不想强制执行,但允许重写,则需要默认的
virtual
方法

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

interface IFoo
{
    string GetFoo();
}

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

class Foo : FooBase, IFoo
{
}
然而,你可能无论如何都不想这样做,这种类型的设计似乎有点荒谬


此外,C#命名约定支持方法名称的标题大小写,因此
GetInt
GetString
。接口的命名约定是以
I
IOptionSet

作为前缀,因为StringBaseDoptionSet没有实现接口,所以类应该是:

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;
        }
    }

}
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;
        }
    }

}

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

Hmm,您的抽象类应该实现接口(因为它似乎是接口的一个具体的基本实现),并按照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;
        }
    }
}

Uups,我的示例代码缺少实现。当我实际尝试它时,它确实实现了接口。抽象类没有实现接口的事实并不是编译器错误的原因。这是因为类中缺少
getString
方法。实现接口只会创建下一个编译器错误,即类没有正确实现接口。该类实际上根本不需要实现接口,这可以在派生类上实现,基类方法将满足接口,但这在很大程度上是毫无意义的。@NiklasR请提供正确的代码。根据提供的代码得到的编译器错误是因为您试图调用一个不存在的方法。
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;
        }
    }
}