![](/img/trans.png)
[英]Call generic method on interface implementation only if implemented in C#
[英]C# calling un-implemented method in abstract interface implementation
这里有一个接口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;
}
}
}
为什么我不能从StringBasedOptionSet.getInt(string)
调用getString(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
我也尝试调用base.getString(key)
OptionsSet.getString(key)
和base.getString(key)
,这导致非静态方法 / 对象不包含getString错误的定义 。
编辑 :那StringBasedOptionsSet
不实施OptionsSet
界面,而剥离下来的例子是错误的。 它确实在我的实际代码中实现了该接口。
您需要在抽象类定义中提供该方法作为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#命名约定倾向于使用方法名称的标题大小写,因此GetInt
和GetString
。 接口的命名约定以I
: IOptionSet
为前缀。
由于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;
}
}
}
您可能还需要在抽象类中再次定义该函数。
嗯,您的抽象类应该实现该接口(因为它似乎是它的具体基础实现),并按照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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.