Reputation: 16890
There's an interface OptionsSet
and an abstract class 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;
}
}
}
Why can't I call the getString(string)
method 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
I also tried invoking OptionsSet.getString(key)
and base.getString(key)
which leads to non-static method / object does not contain definition for getString errors.
Edit: That StringBasedOptionsSet
does not implemented the OptionsSet
interface was a mistake while stripping down the example. It does implemented the interface in my actual code.
Upvotes: 1
Views: 401
Reputation: 64517
You need to provide the method as an abstract
stub or proper method (optionally virtual
) inside your abstract class definition:
public abstract string getString(string key);
Or:
public virtual string getString(string key)
{
return null;
}
This is the template method pattern.
If you intend to force derived types to provide getString
then an abstract
method is required. If you do not want to force it, but allow it to be overridden then a default virtual
method is required.
Note that your abstract class does not need to implement the interface directly, this can be done at the derived class and the interface will still be satisfied so long as the methods are defined correctly:
interface IFoo
{
string GetFoo();
}
abstract class FooBase
{
public virtual string GetFoo()
{
return "Adam";
}
}
class Foo : FooBase, IFoo
{
}
However, you probably wouldn't want to do this anyway, this type of design seems a little nonsensical.
Also, C# naming convention favours title case for method names, so GetInt
and GetString
. Naming convention for interfaces is to prefix with I
: IOptionSet
.
Upvotes: 1
Reputation:
Hmm, your abstract class should implement the interface (since it seems to be a concrete base implementation of it) and implement getString() as abstract methode as Adam suggested.
The result would be
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;
}
}
}
Upvotes: 0
Reputation: 2395
Because StringBasedOptionsSet doesn't implement the interface, your class should be:
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;
}
}
}
You might also need to define the function again in the abstract class.
Upvotes: 1