What is the 'correct' way of providing a value in an abstract class from a concrete subclass?
ie, should I do this:
abstract class A {
private string m_Value;
protected A(string value) {
m_Value = value;
}
public string Value {
get { return m_Value; }
}
}
class B : A {
B() : this("string value") {}
}
or this:
abstract class A {
protected A() { }
public abstract string Value { get; }
}
class B : A {
B() {}
public override string Value {
get { return "string value"; }
}
}
or something else?
And should different things be done if the Value property is only used in the abstract class?
I usually prefer the first approach because it requires less code in child classes.
However, I admit that the semantics of the second approach are clearer in a subtle way. Overriding the property says "this property's implementation is part of my identity." Passing a constructor argument has a different connotation: "I'm setting a value in this other thing, which just happens to be my base class." It implies composition (has-a) rather than inheritance (is-a).
And should different things be done if
the Value property is only used in the
abstract class?
In this case, you should definitely use the first (constructor-oriented) approach so you can hide that implementation detail from subclasses.
Likewise if you need to use the value in the constructor; as Marc mentioned this is an actual technical reason to use the first approach. Though it wouldn't matter in this specific scenario, if someone later modifies the property override to use some other member variable in the derived class, you might have a subtle bug on your hands.
It depends; does the base-class need to know about it in the ctor? If so, the override approach may be a bad idea (virtual doesn't work very well inside the ctor). Otherwise, either is OK.
I think the second idiom is better, as it is more manageable (if your base class needs multiple properties defined in a derived class, the constructor can get messy). It is also clearer where the information comes. If you see the Value property you know that it is defined in a subclass. In the first example, you have to track the definition point of the m_Value variable, which could be modified in the base class.
I think it's pretty much the same, choose one way and stick to that for coherence.
Both your solutions are forcing the derived class to provide a value, which is good; a possible alternative, in case a value should not be required:
abstract class A {
public string Value {
get;
protected set;
}
}
My personal preference is your first option (constructor parameter), because I personally think that it's the clearer one, but it's really a matter of taste.
It depends.
I will use the first way if I need to modify Valuein abstract class.
I will use the second way only if I need to inherit many classes from A and somewhere, I need to box the inherited classes to the base abstract class.
If both of the above are not true, I will use the second approach which is more manageable and clean.
If Value is only used in abstract class, I will declare it as a private field instead of a property.
One major advantage of the second case is that it allows a subclass to define behaviour for the Value property that may be more complex than a simple scalar value. For example, you might want to compute the Value based on other fields that the subclass defines. With the first approach, that is an impossibility, but the second approach allows for that.
I prefer the second. It lets you provide a value without adding an actual field to the class if the value is constant or can be calculated at runtime. The less state you have (fewer fields) the more maintainable you'll likely find the code to be.
Related
I quite often find this kind of code in my company...
class Base
{
public int Property
{
get; set;
}
}
class Derived : Base
{
public Derived()
{
base.Property = 0xAFFE;
}
}
And, i often argue that this kind of use of base is "wrong".
I argue, that "this.Property" would be "correct" (or simply "Property = 0xAFFE;")
I argue, that one could refactor (making Property virtual, override it).
But, my arguments seem not to convince. Can you help with arguments? Or am i (completely) wrong?
Thanx.
I think that, if Property in your example is not virtual, it doesn't matter if you use base or this.
If it is virtual though, and overriden in an inherited class, you'll have differences in behavior.
I personally tend to never use base or this when setting properties like this (which would be the same as specifying this). Only in specific situations (like overriding a virtual method an calling the base implementation) do I use those keywords
So, we have at least 3 ways to say the same:
Property = 0xAFFE;
this.Property = 0xAFFE;
base.Property = 0xAFFE;
And as usual, there are minor aspects that can make a decision why this line is correct or wrong.
First version is most relaxed. Property can be a real property or a variable declared above or a param passed to from outer scope. Moreover, in some cases you can write Property = Property and the compiler would be smart enough to understand you (bad practice anyway).
Second version does an assumption: Property is the class belongings. Period. Despite some code analyzers would rise a hint "syntax can be simplified", this is a normal way of doing things.
Third one intends an assumption that is even more tight: Property is a blessing from ancestors. So even if you override it locally, that syntax 100% ensures you that the change is applied on the ancestor field.
To be honest, in most cases last two syntax forms are interchangeable. Do you really see a point to enforce yours?
I was tracking down a bug and I found this in the Avalon Dock 2.0 source code:
public abstract class LayoutContent : LayoutElement, /* ... */, ILayoutPreviousContainer
{
// ...
[XmlIgnore]
string ILayoutPreviousContainer.PreviousContainerId
{
get;
set;
}
protected string PreviousContainerId
{
get { return ((ILayoutPreviousContainer)this).PreviousContainerId; }
set { ((ILayoutPreviousContainer)this).PreviousContainerId = value; }
}
}
ILayoutPreviousContainer has a member string PreviousContainerId { get; set; }.
What does this pattern accomplish? I understand that you could not get/set the PreviousContainerId from outside the inheritance subtree unless you first cast the LayoutContent to an ILayoutPreviousContainer. But I don't understand why you would want this.
Upon doing research about this pattern, I found this SO post which confused me some more. By implementing it this way, it is seemingly similar to having just a virtual property that would be implemented in a convoluted way:
public class SpecificLayoutContent : LayoutContent, ILayoutPreviousContainer
{
// override LayoutContent.PreviousContainerId since it casts 'this' to an ILayoutPreviousContainer
// which will then call this property
string ILayoutPreviousContainer.PreviousContainerId{ /* ... */ }
}
Am I missing something?
A protected property cannot implement an interface property, implicitly or explicitly. So if you want easy direct access from this class and derived classes, you want one protected property and another "hidden" property which explicitly implements the interface.
Looking at your example, one could consider switching roles of the two properties, such that the protected one was an auto-property, and interface-implementing one was referring to the auto-property (and not the other way around).
What alternative do you see? One could stick to a single property if that was made public (so implementing implicitly), but in that case the property would be exposed much more which is apparently not desired.
ILayoutPreviousContainer seems to be an internal interface. So as far as outside users of SpecificLayoutControl are concerned, the interface doesn't exist, and there is just the PreviousContainerId property defined on the class.
The usual rules apply for whether that should be protected or public. I won't expand on that, since it doesn't seem like that's what your question is about.
The class's authors have decided that the property should be protected. However, if it is protected, it cannot implement the interface's property, and although external users don't see that interface, internally that interface is required elsewhere. So, they implemented it like this, where one property merely forwards to the other.
I was looking at this blog post and had following questions:
Why do we need the new keyword, is it just to specify that a base class method is being hidden. I mean, why do we need it? If we don't use the override keyword, aren't we hiding the base class method?
Why is the default in C# to hide and not override? Why have the designers implemented it this way?
Good questions. Let me re-state them.
Why is it legal to hide a method with another method at all?
Let me answer that question with an example. You have an interface from CLR v1:
interface IEnumerable
{
IEnumerator GetEnumerator();
}
Super. Now in CLR v2 you have generics and you think "man, if only we'd had generics in v1 I would have made this a generic interface. But I didn't. I should make something compatible with it now that is generic so that I get the benefits of generics without losing backwards compatibility with code that expects IEnumerable."
interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh
What are you going to call the GetEnumerator method of IEnumerable<T>? Remember, you want it to hide GetEnumerator on the non-generic base interface. You never want that thing to be called unless you're explicitly in a backwards-compat situation.
That alone justifies method hiding. For more thoughts on justifications of method hiding see my article on the subject.
Why does hiding without "new" cause a warning?
Because we want to bring it to your attention that you are hiding something and might be doing it accidentally. Remember, you might be hiding something accidentally because of an edit to the base class done by someone else, rather than by you editing your derived class.
Why is hiding without "new" a warning rather than an error?
Same reason. You might be hiding something accidentally because you've just picked up a new version of a base class. This happens all the time. FooCorp makes a base class B. BarCorp makes a derived class D with a method Bar, because their customers like that method. FooCorp sees that and says hey, that's a good idea, we can put that functionality on the base class. They do so and ship a new version of Foo.DLL, and when BarCorp picks up the new version, it would be nice if they were told that their method now hides the base class method.
We want that situation to be a warning and not an error because making it an error means that this is another form of the brittle base class problem. C# has been carefully designed so that when someone makes a change to a base class, the effects on code that uses a derived class are minimized.
Why is hiding and not overriding the default?
Because virtual override is dangerous. Virtual override allows derived classes to change the behaviour of code that was compiled to use base classes. Doing something dangerous like making an override should be something you do consciously and deliberately, not by accident.
If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class
However if you don't specify either new or overrides, the resulting output is the same as if you specified new, but you will get a compiler warning (as you may not be aware that you are hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
So it helps you to avoid mistakes and explicitly show what you want to do and it makes more readable code, so one can easily understand your code.
It is worth noting that the only effect of new in this context is to suppress a Warning. There is no change in semantics.
So one answer is: We need new to signal to the compiler that the hiding is intentional and to get rid of the warning.
The follow up question is: If you won't / can't override a method, why would you introduce another method with the same name? Because hiding is in essence a name-conflict. And you would of course avoid it in most cases.
The only good reason I can think of for intentional hiding is when a name is forced upon you by an interface.
In C# members are sealed by default meaning that you cannot override them (unless marked with the virtual or abstract keywords) and this for performance reasons. The new modifier is used to explicitly hide an inherited member.
If overriding was default without specifying the override keyword, you could accidentally override some method of your base just due to the name equality.
.Net compiler strategy is to emit warnings if something could go wrong, just to be safe, so in this case if overriding was default, there would have to be a warning for each overriden method - something like 'warning: check if you really want to override'.
My guess would mainly be due to the multiple interface inheritance. Using discreet interfaces it would be very possible that two distinct interfaces use the same method signature. Allowing the use of the new keyword would allow you to create these different implementations with one class, instead of having to create two distinct classes.
Updated ... Eric gave me an idea on how to improve this example.
public interface IAction1
{
int DoWork();
}
public interface IAction2
{
string DoWork();
}
public class MyBase : IAction1
{
public int DoWork() { return 0; }
}
public class MyClass : MyBase, IAction2
{
public new string DoWork() { return "Hi"; }
}
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
var ret0 = myClass.DoWork(); //Hi
var ret1 = ((IAction1)myClass).DoWork(); //0
var ret2 = ((IAction2)myClass).DoWork(); //Hi
var ret3 = ((MyBase)myClass).DoWork(); //0
var ret4 = ((MyClass)myClass).DoWork(); //Hi
}
}
As noted, method/property hiding makes it possible to change things about a method or property which could not be readily changed otherwise. One situation where this can be useful is allowing an inherited class to have read-write properties which are read-only in the base class. For example, suppose a base class has a bunch of read-only properties called Value1-Value40 (of course, a real class would use better names). A sealed descendant of this class has a constructor that takes an object of the base class and copies the values from there; the class does not allow them to be changed after that. A different, inheritable, descendant declare a read-write properties called Value1-Value40 which, when read, behaves the same as the base class versions but, when written, allows the values to be written. The net effect will be that code which wants an instance of the base class that it knows will never change can create a new object of the read-only class, which can copy data from a passed-in object without having to worry whether that object is read-only or read-write.
One annoyance with this approach--perhaps someone can help me out--is that I don't know of a way to both shadow and override a particular property within the same class. Do any of the CLR languages allow that (I use vb 2005)? It would be useful if the base class object and its properties could be abstract, but that would require an intermediate class to override the Value1 to Value40 properties before a descendant class could shadow them.
I have a class which derives from an Interface. Now the class has to implement all the methods in the Interfaces + it additionally defines 2 more methods.
Now my question is , what is the benefit/usecases of doing this:
IMyInterface varInt= new ConcreteImp();
over,
ConcreteImp varInt= new ConcreteImp();
I see this pattern used every where in code blocks, but not sure why this is used.
Benefit in using interfaces is in decreasing dependency of parts on concrete implementation of a software component. In one line you posted, you won't be able to see a benefit. Benefit can be gained in consumers of that interface.
Edit: You would be well to read this article on abstractions.
For example, lets say that you have a method which accepts an interface like so Rent(IMovie). Another person will be able to write implementation of Rent() method without knowing specifics of IMovie type which you will pass in when calling the method. You will then be able to create multiple different IMovie implementations which may have different method of billing, but Rent() method doesn't have to take care of that.
void Rent(IMovie movie)
{
var price = movie.Price();
movie.MarkReserved();
}
public interface IMovie { }
public class Oldie : IMovie
{
private decimal _oldieRate = 0.8;
public decimal Price()
{
return MainData.RentPrice * _oldieRate;
}
public decimal MarkReserved()
{
_oldiesDb.MarkReserved(this, true);
}
}
public class Blockbuster : IMovie
{
private decimal _blockbusterRate = 1.2;
public decimal Price()
{
return MainData.RentPrice * _blockbusterRate ;
}
public decimal MarkReserved()
{
_regularDb.MarkReserved(this, true);
}
}
This is example of why interfaces are useful, but is not very nice example of code design.
As a rule of thumb, you should write methods so that they require least input they need to work, and that their output provides as much information for others to use when they call it. For example, take a look at following signature:
public List<Entity> Filter(IEnumerable<Entity> baseCollection){ ... }
This method requests only IEnumerable<Entity> so it can take different collection types, like List<Entity>, Entity[] or custom types some tool returns. But you return List<Entity> so that right away you are not limiting caller to just enumerable elements. She can use Linq on return value right away for example.
There are more benefits, like in unit testing, where you can create mock objects and tell them how to behave during interaction with rest of the code. Although, you can do this with classes with virtual methods now.
Suppose that you want, elsewhere in the code, to be able to assign a different implementation of IMyInterface to the varInt variable. Then that variable needs to be declared with type IMyInterface.
Alternatively, if you want to make it clear to any code readers that all you intend to do with varInt is use the interface defined by IMyInterface, then the type declaration makes that clear.
When you need to enforce functionality in the derived class use interface.
and when you need to pass data from super class to subclass then you use concrete class. Its the basic oop idea behind interface and subclass.
In your concrete example I would say it doesn't matter as much since you are using new and creates a concrete type. When you start using dependency injection it starts to be more useful.
A scenario where it is more useful looks like the following:
public SomeResultType DoSomething(ISomeType obj)
{
//to something with obj
// return someResultType
}
The above can be called using any type as long as it implements ISomeType. But in your example using the new keyword I would instead use var. You will still be able to treat it as type it implements since it inherit that type.
assume that IMyInterface have "Draw" method, now all derived classes have to implement "Draw" method. if you have a class "Engine" with a method "Render(IMyInterface shape)", you have only to call the "Draw" method no matter what the shape is. and every shape Draw itself as he wants.
you can take a look at Design Patterns and you can see the magic of interfaces ;)
Lets take an example in C#
public class Foo
{
public Foo() { }
public Foo(int j) { }
}
public class Bar : Foo
{
}
Now, All the public members of Foo is accessible in Bar except the constructor.
I cannot do something like
Bar bb = new Bar(1);
Why the constructors are not inheritable?
UPDATE
I do understand we can chain constructors, but I would like to know why the above construct is not valid. I am sure there should be a valid reason for it.
Constructors are not inheritable because it might cause weird and unintended behavior. More specifically, if you added a new constructor to a base class, all derived classes get an instance of that constructor. That's a bad thing in some cases, because maybe your base class specifies parameters that don't make sense for your derived classes.
A commonly given example for this is that in many languages, the base class for all objects (commonly called "Object") has a constructor with no parameters. If constructors were inherited, this would mean that all objects have a parameterless constructor, and there's no way to say "I want people who make an instance of this class to provide parameters X, Y and Z, otherwise their code shouldn't compile." For many classes, it's important that certain parameters be defined for their proper function, and making constructors non-heritable is part of the way that class authors can guarantee that some parameters are always defined.
Edit to respond to comments: Ramesh points out that if constructors were inherited as he would like them to be, he could always override base class constructors using privately declared constructors in each derived class. That is certainly true, but there it a logistical problem with this strategy. It requires that writers of derived classes have to watch base classes closely and add a private constructor if they want block inheritance of the base class constructor. Not only is this a lot of work for people writing derived classes, this kind of implicit dependency across classes is exactly the sort of thing that can cause weird behavior.
Ramesh - it's not that what you describe would be impossible to add to a language. In general it's not done because that sort of behavior could confuse people and lead to a lot of extra debugging and code writing.
Quintin Robinson provides some very worthwhile responses to this question in the comments that are definitely worth reading.
They are (via chaining), you would have to chain the constructor in your derived object.. IE:
public class Foo
{
public Foo() { }
public Foo(int j) { }
}
public class Bar : Foo
{
public Bar() : base() { }
public Bar(int j) : base(j) { }
}
The constructors in the derived objects will then chain the calls do the constructors in the base objects.
This article provides some more examples if you want further reading.
One reason why you might introduce a constructor into a class is because it makes no sense to have an instance of that class without a specific "dependency". For example, it might be a data-access class that has to have a connection to a database:
public class FooRepository
{
public FooRepository(IDbConnection connection) { ... }
}
If all the public constructors from base classes were available, then a user of your repository class would be able to use System.Object's default constructor to create an invalid instance of your class:
var badRepository = new FooRepository();
Hiding inherited constructors by default means that you can enforce dependencies without worrying about users creating "invalid" instances.
Suppose constructors were inheritable. How would you disable the inherited constructors in the many cases were they don't make sense for a subclass?
Rather than complicating the language with a mechanism to block inheritance, the language designers opted for simply making constructors not inheritable.
The Foo constructor can only know how to initialize a Foo object, so it makes no sense that it should also know how to initialize any potential subclass
public class Bar : Foo
{
public Bar(int i) : base(i) { }
}
The story the constructor tells is: "Hey base class please do whatever work you need to do to be in a good state so that I can go ahead and set up myself properly".
Constructors are not inheritable for design reasons. (Note that this is the same situation in every object-oriented language of which I know.) The simple answer is that in many cases you'd really not want the same constructors as the base class to be available. See this SO thread for some more complete explanations.
Some discussions
Joel's forum
Eric Gunnerson's blog
The basic idea is to provide as much control to the creator as possible. And you can have private bases. How'd you create the object then?
I think you can do the following:
public class Bar : Foo
{
public Bar (int i)
: base (i)
{
}
}
I may be a bit off -- but it's the general idea.
The simple answer is that the language doesn't work that way.
The real question you are asking for though is why it doesn't work that way :-) Well it is an arbitrary choice, and it follows on from C++ and Java (and very possibly many other langauges that influenced C#).
The likely reason is that the compiler will only generate a constructor that takes no arguments and simply calls the parent is that if you want more than what the compiler makes you do it yourself. This is the best choice since odds are you do more than suply calling the parent constructor.
Really, its because the parent constructor wouldn't fully initialize the child object. A constructor is kind of a personal thing in that respect. That's why most languages don't inherit constructors.