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.
Related
I have an abstract class that does its own internal validation. It has another method that allows subclasses to do additional validation checks. Currently, I've made the method abstract.
protected abstract bool ValidateFurther();
However, I'm seeing quite a number of subclasses being forced to override it just to return true. I'm considering to make the method virtual.
protected virtual bool ValidateFurther() => true;
Is it bad to assume that validation is going to be fine in the abstract class? I'm worried that subclasses may not notice it and ended up not overriding it even when it is needed. Which is the more suitable approach here?
You could add another layer into your design.
public abstract class Base
{
protected abstract bool ValidateFurther();
}
public abstract class BaseWithValidation : Base
{
protected override bool ValidateFurther() => true;
}
If a significant subset of your inherited classes should just return true you can use BaseWithValidation to avoid having to repeat the code everywhere; for anything else use Base.
abstract method means you just want to define the behavior to be followed, and let sub classes do the implementation.
virtual method means you defined an method with initial implementation, but allow to be override.
So maybe you can explain you context more, then we can discuss it!
It's okay to make the method virtual and define a default implementation returning true.
protected virtual bool ValidateFurther() => true;
The difference between abstract and virtual is that that abstract methods defines only the signature of a method and the implementation is left to be implemented by the derived classes(similar to an interface). All child classes are required to implement the logic of an abstract method. You can see the documentation for more details.
Virtual on the other hand requires you to implement the logic and if needed you can override that method to add/extend the logic. And because you have default logic your child/derived classes are not required to override it. You can see the documnetation for more details.
Basically it is okay to implement the method as virtual and return true; by default.
FYI: From C# 8 you can have default implementations in the interfaces link
The short answer
If this class' (and all of its derived class') purpose does not always necessitate validation, then you should go with virtual, otherwise abstract.
In other words, is validation a cornerstone of this class' purpose? (yes = abstract, no = virtual)
I suspect that virtual is the better approach here, but not for the reason you're thinking it is. The rest of this answer elaborates on why your reasoning isn't the deciding factor here, and what actually is the deciding factor.
Your reasoning
I'm seeing quite a number of subclasses being forced to override it just to return true.
I suspect you're succumbing to the programmer's reflex: "I see this repeated and must write code to avoid this repetition!"
While that is generally a good approach, it can also be misapplied when you start applying this to things that happen to be the same rather than expressing the same functional purpose.
The example I tend to use to address that point is the following:
public class Book
{
public string Title { get; set; }
public DateTime CreatedOn { get; set; }
}
public class EmployeeJob
{
public string Title { get; set; }
public DateTime CreatedOn { get; set; }
}
There is definitely value to abstracting the CreatedOn property, as these entities are both audited data entities. The CreatedOn property is part of that audited entity, and its existence in both Book and EmployeeJob stems from these classes both being audited entities.
If a change is made to audited entities (e.g. they no longer track creation date), then that change needs to automatically persist to all audited entities. When you use shared logic, that automatically happens.
But does Title need to be abstracted into a shared logic? No. There is no functional overlap here. Yes, these properties have the same name and type, but they share no common logic whatsoever. They just happen to be equal to each other right now, but they are not tied to one another.
If a change is made to one Title property (e.g. it now becomes a Guid FK to a table of job titles), that change doesn't automatically reflect on the other (e.g. a book title would still just be a string). Implementing these Title properties using shared logic would actually cause a problem down the line instead of solve one.
In short: sometimes programmers seek more patterns than they need. Or if you allow me to quote Jurassic Park...
The deciding factor
I'm considering to make the method virtual.
Whether you make it abstract or virtual depends on one specific considerations (not DRY, as addressed above): Do you wish to provide a default implementation, or would you prefer to enforce that every consumer (i.e. derived class) evaluate the implementation of this method for themselves?
Neither of these are objectively better than the other, it's a matter of which fits best for you current scenario.
I'm seeing quite a number of subclasses being forced to override it just to return true.
I infer from this that you're essentially skipping validation in these classes, so in this case I would opt for the virtual approach since this class' (and all of its derived class') purpose does not always necessitate validation (again, that is my interpretation based on your explanation).
In other words, is validation a cornerstone of this class' purpose? (yes = abstract, no = virtual). You didn't specify your class or its purpose so I can't make that final call.
I am trying to setup a scenario where we can create a common set of models for our workgroup and then implement or extend them if/when needed.
I have the following setup:
namespace Workgroup.DomainClasses
{
public abstract class WorkGroupOrder
{
private ICollection<WorkGroupItems> _items;
protected WorkGroupOrder()
{
_items = new List<WorkGroupItems>();
}
protected int OrderId { get; set; }
protected virtual ICollection<WeAccount> Items
{
get { return _items; }
set { _items = value; }
}
}
}
I would prefer that users not use the base WorkGroupOrder so would like to set this up so they are required to implement their own version of the class. If all is good with the base class it would simply be an empty class calling the base constructor but otherwise properties and functionality could be added. The idea for this is that the Workgroup domain is much larger than may be necessary for a single project but we'd like to drive all work from this common model.
using Workgroup.DomainClasses;
namespace Project.DomainClasses
{
public class Order : WorkGroupOrder
{
public string OrderComment { get; set; }
}
}
The issue I'm having is that I'm required to reference both domain models to implement. There is an error below in the Testing() method that I must also reference Workgroup.DomainClasses in order to instantiate the class. I'm not that familiar with abstract classes so is this just the nature of the abstract type? I'd prefer to remove this dependency if possible.
using Project.DomainClasses;
namespace Project.DataLayer
{
public class Testing
{
public void Testing()
{
Order o1 = new Order();
}
}
}
A few questions.
Does this organization make sense or is there a better way to
support my desire of providing a common model that could potentially
be extended?
How would I access the properties of both the base
abstract class and the concrete class? In my Testing() method I am unable
to access `o1.OrderId` for example.
I'd like to remove meta-knowledge of the abstract class from the developer. How would it be best to execute the constructor without explicitly requiring the developer to do so?
Ultimately I'd like to require developers to create their own instance of the class to avoid implementing the base model directly. I'd also like to build in the proper visibility to prevent them from going directly to the Workgroup objects.
It seems like there are a few different issues in play here.
Firstly, using a namespace to try to segregate out base functionality is not a viable option because all derived classes will need access to the namespace of the base class by default (in order to inherit). Any developers extending your base classes will need access to the namespace containing the base classes.
Controlling access to functionality or data is generally best accomplished using access modifiers (eg, public, protected, or private) or public properties with public get{ } and protected set{ } or private set{ } (ie, getters and setters with different acccess levels). If you wish to hide implementation details from the end users, then an interface is the right approach to take (like an API, for example).
Secondly, by marking any class abstract you will automatically deny other developers the ability to instantiate that class directly. They will be forced to create a class derived from the abstract class (aka, a "concrete" class) in order to use the abstract base class's methods and properties.
Third, the reason you couldn't access property o1.OrderId in your test code is because that property has an access modifier of protected. This means that only the base class and its derived classes can internally access this property. To expose it to the end user, it must be marked public.
Unfortunately, I do not really understand what you mean with "setup a scenario where we can create a common set of models for our workgroup and then implement or extend them if/when needed". What is a workgroup in your context? And why should (all) other classes derive from it?
Anyway, you cannot use o1.OrderID because this property is protected which means it is only visible within the scope of WorkOrderGroup and subclasses that derive from it. Make this property public and you can access it everywhere.
Furthermore, and please take no offence, but it seams that you somewhat struggle with the object-oriented concepts of encapsulation and inheritance. I would advise you to have a look at these concepts (you can e.g. start here) and get a good understanding what they do and how to use them when implementing functionality. With the current information, I would not advise you to structure your code like you explained in your question.
Finally, some general hints on practices in object-oriented languages:
Favor composition over inheritance: this means that you should extend existing classes by encapsulating them instead of inheriting from them. In most cases this is more flexible.
Take a look at the SOLID princples: they provide really good instructions that you should consider on every class you write.
Take a look at Design Principles and maybe Domain-Driven-Design: there is a lot of guidance on the internet out there with a lot of examples. With every examples you get a better feeling how to approach new problems and how to model them in OOD.
I hope this answer guides you in the correct direction.
When I googled to find the related topics about interface, I found this from MSDN website:
For example, an interface might declare a property that has a get accessor. The class that implements the interface can declare the same property with both a get and set accessor.
from MSDN
Now I have a doubt. When we specifically mentioned that the property should be read only(only 'get' accessor in the interface) why is it allowed to implement 'set' accessor also?
Now I have a doubt. When we specifically mentioned that the property should be read only(only 'get' accessor in the interface) why is it allowed to implement 'set' accessor also?
There's a difference - when you use an interface, you're not "specifying that the property should be read only", but rather specifying that the contract defines a "readable property" of that specific name and type. Basically, the interface defines the minimum requirements for a contract, not the absolute requirements.
If you cast the object to the specific interface, the property setter will not be available. It's really no different than having extra properties or methods on the object that aren't available via the interface.
You can't access the set property from a interface reference, so it doesn't matter if it's implemented or not when revealing the interface to the public.
Of course it's sometimes necessary to implement a set accessor on class side, i.e. when working with a class which allows access of classes which are in the same assembly.
Interface is a minimum set of requirements that needs to be implemented but you can implement more. In this case read-write property is more than just read-only one.
Besides extending beyond requirements of a contract you can add any other methods and/or properties and also implement other interfaces in the same class.
The code which uses the interface does not know that there is a set and so can't use it.
Think of an interface as a contract. Implementers promise to at least comply to the behaviors defined in that contract, but are not restricted to it. Interfaces allow components to interact without being tightly coupled. Therefore, an implementation may allow both get and set, but at the very least must honor the get.
The class is meeting the requirements of the interface, anything else is an implementation detail of the class itself. If you're referring to the object through the interface, you're only going to see the get. So, no, it's not really breaking it, it's as intended.
The interface though is just a declaration of how the object should be used by consumers. It doesn't make any specifications about the implementation. There's no inconsistency there.
public interface IFoo {
string Name { get; }
}
class FooImplementation : IFoo {
public string Name { get; set; }
}
public class FooWorker {
public void WorkOnFoo(IFoo foo) {
if (null == foo) throw new ArgumentNullException("foo");
Console.WriteLine(foo.Name);
}
}
public class Program {
public void Main() {
IFoo foo = new FooImplementation { Name = "Foo" };
new FooWorker().WorkOnFoo(foo);
}
}
As far as FooWorker is concerned, the foo parameter only has a get accessor for the Name property.
It's probably important to remember that that the Name property may still be set on foo via reflection or a cast.
What Felix said is correct.
In more detail, an interface defines a minimum set of functionality that must exist on any object defined as implementing said interface. That provides a "common" set of functionality among all implementations of the interface, so you know that if an object implements the interface, you can call X, Y, and Z on it. Just because something is IDisposable, for instance, doesn't mean that's ALL the object can do. In fact that would make interfaces rather pointless, if they also defined a maximum amount of functionality. That's just all you care about if and when you are working with the object as an implementation of the interface; if all you need is an IDisposable, you only care about calling Dispose(), regardless of what additional members a particular IDisposable implementation may have.
Back to your example, the interface defining the property is stating that it must have a public get accessor. It does not, and cannot, say that it cannot have a public set accessor; it simply doesn't care either way. The set accessor could be public, internal, protected, private, or nonexistent; what consumers of the interface will expect, and thus what implementors of the interface will need, is the get accessor.
It may be helpful to think in terms of three types of things: an abstract ReadableFoo class (or IReadableFoo interface), along with concrete ImmutableFoo and MutableFoo classes (or IImmutableFoo and IChangeableFoo interfaces). Someone who receives a parameter of type ReadableFoo will be able to read it, but will not be able to set it, and will not be able to reliably persist the data therein merely by persisting a reference. Someone who receives a parameter of ImmutableFoo would be able to reliably persist the data by persisting the reference, but would not be able to change it. Someone who receives a parameter of MutableFoo will be able to change the data, but not reliably persist data by persisting the reference.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
C#: Public Fields versus Automatic Properties
Duplicate? I think not:
This question is not the same as "Why
use properties instead of public
field". A property with a specified
getter and setter is far different
than a public field. My question was,
is a property WITHOUT a getter and
setter, any different.
With the somewhat recent ability to have empty getters and setters, what is the benefit of using them instead of just declaring a public member variable?
Example:
public string MyProperty
{
get;
set;
}
versus:
public string MyProperty;
One word: inheritance.
Properties are inheritable while fields are not. You can use fields in an inherited class, but not alter their behavior by making them virtual.
Like so:
public class Foo {
public virtual int MyField = 1; // Nope, this can't
public virtual int Bar {get; set; }
}
public class MyDerive : Foo {
public override MyField; // Nope, this can't
public override int Bar {
get {
//do something;
}
set; }
}
Edit: Besides the fact of inheritance, the points pointed out in the other answers (like visibility) are also a huge benefit of properties over fields.
One thing you can do with properties that you can't do with fields is limit visibility for either setter or getter:
public string MyProperty { get; private set; }
Something I use quite a lot.
And something (more powerful) you can't do with fields is define them inside an interface. Suppose you want an interface that requires implementing classes to have a certain property:
public interface MyInterface
{
string MyProperty { get; }
}
Note that you do not need to have a setter here. It is entirely up to implementing classes to determine how they should set MyProperty.
Fields cannot be exposed in interfaces. And the auto-property can be changed into a "normal" property at any time if needed, without having the signature and interface of the class changing.
In general, fields are considered to be an implementation detail, which may change in future versions of the code. Therefore, you should expose data via methods and properties, leaving the way open for internal changes in the future which do not affect code using the class.
A property gives you several advantages over a simple public field:
you can control whether the property is read-only, write-only, or read/write
you can hide the actual implementation (maybe in the setter you want to do more than just setting a value)
when using databinding (e.g. in ASP.NET), you'll have to use properties (does not work with fields)
Tight coupling comes to mind. Using public fields removes the layer of abstraction made available by the use of properties. Using private fields and properties hides the implementation from other classes and helps to insulate them (external classes) whenever a change is necessary.
Also, keep in mind that you are referring to auto-implemented properties which causes the compiler to create the backing field for you instead of you having to manually create the backing (private) field for each property on your class.
The idea is to manage the values inside of the object, state, avoiding corruption and misuse by calling code.
You can flag properties with attributes that aren't available on members. There are attributes that only apply to fields in the DataContract namespace that affects serialization, the attribute can't be applied to fields, etc.
Admittedly, there isn't anything technically preventing these attributes from being used on members, but nonetheless they only work on properties.
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.