C# compiler complains that abstract class does not implement interface? - c#

I have a nice interface, and I want to implement one member of it in a base class so the clients can derive from the base class and have less boiler-plate to write. However, even though declared abstract, the compiler complains that the class does not implement the interface?!? How is this supposed to be done?
Code in question:
public interface ITaskDefinition
{
ITask CreateTask(TaskId id);
string Name { get; }
bool HasName { get; }
}
public abstract class TaskDefinitionBase : ITaskDefinition
{
private string name_ = null;
public void SetName(string name)
{
name_ = name;
}
public string Name
{
get
{
return name_;
}
}
public bool HasName
{
get
{
return name_ != null;
}
}
}
and the error I get is:
ITaskDefinition.cs(15,27): error CS0535: 'NetWork.Task.TaskDefinitionBase' does not implement interface member 'NetWork.Task.ITaskDefinition.CreateTask(NetWork.Task.TaskId)'

You must add an abstract stub of the method:
public abstract ITask CreateTask(TaskId id);
Inheritors can then override it to implement the interface.

When an object implements an interface it must obey all the constraints applied by the interface. This means that you must implement all properties and methods declared in the interface.
In your case you're missing the implementation of CreateTask. Also, you should note that C# use properties as opposed to Java for example that uses getters/setters. For this reason you don't need a SetName method.
You code should look something like this:
public abstract class TaskDefinitionBase : ITaskDefinition
{
private string name_ = null;
public abstract ITask CreateTask(TaskId id);
public string Name
{
get
{
return name_;
}
set
{
name_ = value
}
}
public bool HasName
{
get
{
return name_ != null;
}
}
}

TaskDefinitionBase needs to include CreateTask - if you don't want to implement it, just mark the method as abstract to force any implementing classes to implement it.

Related

Unwanted setter of virtual string property, in derived class

Is there a better way of doing the following ...
I have a base class which provides a default implementation of the DisplayName property. Obviously optionally set, not required.
Edit: I can't use an interface instead of this base class, because I have behavior in it, which is trimmed out in this example.
public abstract class BaseObject
{
public virtual string DisplayName { get; protected set; }
public BaseObject(string displayName)
{
if (!string.IsNullOrWhiteSpace(displayName))
{
this.DisplayName = displayName.Trim();
}
}
// There is common behavior, unrelated to DisplayName here ... trimmed out of this sample code.
}
I have a system object class, derived from BaseObject, but providing its own implementation of DisplayName
public class SystemObject : BaseObject
{
public override string DisplayName
{
get
{
return string.Format("TODO: Resources.{0}", this.Id);
}
// EDIT: Turns out I can't even do that, because EF can't materialize the property. So, it needs to be an empty protected setter.
protected set { throw new InvalidOperationException("Do not set this property!"); }
}
public SystemObject() : base(null)
{
}
}
and I have a user-defined object, derived from the same base class:
public class UserObject : BaseObject
{
public UserObject(string displayName) : base(displayName)
{
if (string.IsNullOrWhiteSpace(displayName))
{
throw new ArgumentNullException("displayName");
}
}
public void ChangeDisplayName(string newDisplayName)
{
if (string.IsNullOrWhiteSpace(newDisplayName))
{
throw new ArgumentNullException("newDisplayName");
}
this.DisplayName = newDisplayName.Trim();
}
}
which utilizes the DisplayName from BaseObject to store a user-provided display name.
I can't make the DisplayName in BasObject abstract, because I am doing EF code first.
I am particularly concerned about protected set { throw new InvalidOperationException("Do not set this property!"); }. Any way to avoid this?
Don't use an abstract class at all when you don't actually want to define any behavior. If you just want a way of saying that there are different objects with a DisplayName property getter, then create an interface that defines such a contract that these two classes can implement in their own ways.
I think I see where you are going with this.
Leave the property alone. Just make it a get-only property in the base class, but make the getter call an abstract method:
public string DisplayName { get { return GetDisplayName(); } }
Then declare the method as abstract:
protected abstract string GetDisplayName();
That will force your inheriting classes to provide an implementation of how to return a display name. You can then change your UserObject class to store the name internally during instantiation and return it in the implementation of the method.
You could simply stub it out to do nothing;
public string DisplayName { set {} ...}

How to correctly override and enhance property

Code tells more than words, so look at this:
public abstract class ViewObject: INotifyPropertyChanged {
public virtual string Id {
get {
return this.GetType().Name;
}
}
}
public class Object : ViewObject {
private string id = string.Empty;
public override string Id {
get {
return this.id;
}
set {
this.id = value;
}
}
}
What is the correct way to implement the desired behaviour of a base implementation in the abstract class (yes, it should have a base implementation for this, but not for other things)?
I can only think of using the new keywork instead of override to simply hide the base implementation, but is this right?
you are already using inheritance. Override method is useful when method name and parameter is same.
here you can use method overloading.
for method overload name is same but parameter is different. you can use in inheritance also.
i hope this is useful
If you use the new keyword and someone casts your derived object to the base class, the base implementation will be called and not the derived one. To avoid this, the override is needed.
But that is currently not possible, cause your base class doesn't support a setter. So stick to the override and implement a set method in the base class that simply throws a NotSupportedExecption.
public abstract class ViewObject
{
public virtual string Id
{
get { return this.GetType().Name; }
set { throw new NotSupportedException(); }
}
}
public class Object : ViewObject
{
private string id = string.Empty;
public override string Id
{
get { return this.id; }
set { this.id = value; }
}
}

How to make the interface enforce the implementation not having a setter?

following the example:
interface ISomeInterface
{
string SomeProperty { get; }
}
I have the implementation that compiles:
public class SomeClass : ISomeInterface
{
public string SomeProperty
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
which is a problem. How do I make the interface a contract that, won't allow set in it's implementation?
notice: I'm not looking for a solution how to avoid set IN the implementation but in the interface that will validate it from any new implementation, thanks.
Interfaces only specify what MUST be implemented, but do not restrict what other methods, or properties may also be implemented.
So the get is the only thing that you have specified.
Since you are silent on the set, any implementer of the interface is at liberty to add or not to add the set.
In short, with an interface specification you cannot do what you want to do.
If you want to make sure the set is never called then you could always cast the instance to the Interface
If you really need to make sure there is no set you could use an abstract class instead of an interface
abstract class SomeInterface
{
virtual string SomeProperty { get; }
}
Based on Mike answer, you could write something like that :
public interface ISomeInterface
{
string SomeProperty { get; }
}
public abstract class SomeInterfaceBase : ISomeInterface
{
public abstract string SomeProperty { get; }
}
So you can define your class like that:
public class SomeClass : SomeInterfaceBase
{
public override string SomeProperty { get; }
}
If you try to implement a setter, it will not compile.
Having a setter isn't an issue. The reason for this is because of how we treat interfaces.
Whether the concrete class has a setter or not does not matter, because we are supposed to treat the object as an ISomeInterface. In this case it only has a setter.
For instance lets take a factory method:
class Program
{
interface ISomeInterface
{
string SomeProperty { get; }
}
static ISomeInterface CreateSomeClass()
{
return new SomeClass();
}
class SomeClass : ISomeInterface
{
public string SomeProperty
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
static void Main(string[] args)
{
ISomeInterface someInterface = CreateSomeClass();
someInterface.SomeProperty = "test"; //Wont compile
}
}
The class's implementation of a setter is meaningless, because we are only interested in treating the object as ISomeInterface. Interfaces are additive. In other words, they define a contract of what needs to be defined, rather than what should not.
If I was to treat it in any other way, it would be something like this:
((SomeClass) someInterface).SomeProperty = "test"; //Code smell
which I would consider a code smell, because it's assuming that someInterface is SomeClass (treating interfaces as concrete classes)

How to use a derived property on a base class?

I have a base class that has a property and a method that uses that property. I have a class that inherits that base class and has its own implementation of the base class's property that is explicitly hidden using the New modifier. In the base class' method, is there a good way to use the inherited class' property instead of the base's implementation?
class Program
{
public class MyBase
{
public string MyProperty { get { return "Base"; } }
public string MyBaseMethod()
{
return MyProperty;
}
}
public class MyInherited : MyBase
{
public new string MyProperty { get { return "Inherited"; } }
}
static void Main(string[] args)
{
List<MyBase> test = new List<MyBase>();
test.Add(new MyBase());
test.Add(new MyInherited());
foreach (MyBase item in test)
{
Console.WriteLine(item.MyBaseMethod());
}
}
}
In the example, the output is:
Base
Base
Current workaround:
...
public class MyBase
{
public string MyProperty { get { return "Base"; } }
public string MyBaseMethod()
{
if (this is MyInherited)
{
return baseMethod(((MyInherited)this).MyProperty);
}
else
{
return baseMethod(MyProperty);
}
}
private string baseMethod(string input)
{
return input;
}
}
...
Is there a better way to do this? I'd rather not have to do explicit type casts.
Hiding a member with the new keyword should generally be avoided. Instead make the base class' property virtual and override it in the descending class. The MyBaseMethod will automatically use this overridden property in inheriting classes.
public class MyBase
{
public virtual string MyProperty { get { return "Base"; } }
public string MyBaseMethod()
{
return MyProperty;
}
}
public class MyInherited : MyBase
{
public override string MyProperty { get { return "Inherited"; } }
}
var inherited = new MyInherited();
Console.WriteLine(inherited.MyBaseMethod()); // ==> "Inherited"
See this interesting post related to the new keyword: Why do we need the new keyword and why is the default behavior to hide and not override?
Make the property virtual, not sealed, and override it, rather than shadowing it. Then all uses of the property will use the most derived implementation of it.
There is no such way. If you do new (which is early binding), you have to do explicit casts. The only solution is to make the property virtual. Then you can override it (using the override modifier). This is late binding.

Dynamic implementation of an Interface

Suppose I have an Interface with some properties:
public interface IDummy
{
string First {get;set;}
string Second {get;set;}
string Third {get;set;}
string Fourth {get;set;}
}
Now, I have a class which implements that interface:
public class DummyClass: IDummy
{
// ...
}
Is it possible, not to implement the interface properties explicitly and instead use DynamicObject? For example:
public class DummyClass: DynamicObject, IDummy
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
// Get the value from a Config file or SQLite db or something
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// Get the value to a Config file or SQLite db or something
}
}
I am just curious if this is possible or not?
Thanks.
No, this is not possible.
If you are implementing an interface, you need to implement all of its members. C# is still a statically typed language, after all.
When you say a type implements an interface, you are saying it conforms to its contract. Not implementing all of the members means that you are not complying with the contract.
The compiler would see your code and will not assume that you have implemented the contract correctly (in a dynamic fashion) - it will fail to compile.
No, basically. An interface is for static typing; to satisfy an interface your type must actually provide a regular (non-dynamic) implementation. You could not claim to implement it (IDummy), and detect the names, but that could relate to any interface that uses those same names, not just IDummy.
You could make a wrapper.
class DummyWrapper : IDummy
{
private readonly DynamicObject _wrapped;
public DummyWrapper(DynamicObject wrapped)
{
_wrapped = wrapped;
}
string First
{
get { return _wrapped.First; }
set { _wrapped.First = value; }
}
string Second
{
get { return _wrapped.Second; }
set { _wrapped.Second = value; }
}
string Third
{
get { return _wrapped.Third; }
set { _wrapped.Third = value; }
}
string Fourth
{
get { return _wrapped.Fourth; }
set { _wrapped.Fourth = value; }
}
}
You might also be interested in these questions:
Automatically creating a wrapper to implement an interface
Dynamically implementing an interface in .NET 4.0 (C#)

Categories

Resources