Reputation: 4443
For example I have base class and I need a property that
will be calculated in derived classes.I have two variant (SomeProperty1
and SomeProperty2
):
public class BaseClass
{
public int SomeProperty1{get;set;}
public override int SomeProperty2{get;set;}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
SomeProperty1 = 100;
}
public override int SomeProperty2
{
get
{
return 100;
}
}
}
The questions is what is the best way, SomeProperty1
or SomeProperty2
?
Upvotes: 4
Views: 2206
Reputation: 14912
That strongly depends on the type of calculation. If it takes long and it does not change during the lifetime of the object, than you would waste calculation time by adding it in the property. So in that case I would definitely keep your code clean and initialize the property in your constructor.
If it's a constant value, it will be more clear to keep it in the constructor. Your constructor reflects how your object will look like.
Obviously, if the calculation is something dynamic, you would need to have that part in the property.
Note: if you have a virtual property and you initialize it on your constructor, than you will introduce a warning if your class is not sealed
. The 'danger' behind this is explained in this thread better than I can.
Upvotes: 0
Reputation: 109567
Add to the base class a protected abstract method called CalcSomeProperty()
.
Then implement your property in terms of CalcSomeProperty()
. That will force the derived classes to implement it.
For example:
public abstract class BaseClass
{
public int SomeProperty
{
get
{
return CalcSomeProperty();
}
}
protected abstract int CalcSomeProperty();
}
Alternatively, you can make the property itself abstract:
public abstract class BaseClass
{
public abstract int SomeProperty { get; }
}
In either case, you are forcing derived classes to implement the property calculation.
An advantage of separating the calculation into a protected method (rather than using the simpler abstract property) is that you can perform caching in the concrete property implementation if the calculation is slow:
public abstract class BaseClass
{
protected BaseClass()
{
_someProperty = new Lazy<int>(CalcSomeProperty);
}
public int SomeProperty
{
get
{
return _someProperty.Value;
}
}
protected abstract int CalcSomeProperty();
private readonly Lazy<int> _someProperty;
}
Upvotes: 4
Reputation: 1659
If you really mean overriding in child classes, then perhaps you wanted the property to be virtual:
public virtual int SomeProperty2{get;set;}
Although I'd better have a public property declared in base class and a protected virtual property which can be overridden in child classes:
// base
protected virtual int SomePropertyInternal2
{
get
{
return 10;
}
}
public int SomeProperty2
{
get
{
return SomePropertyInternal2;
}
// child
protected override int SomePropertyInternal2
{
return 100;
}
In this case you would have an internal implementation overridden, while a public contract remains intact.
Upvotes: 0
Reputation: 37770
Option 1 is mostly for use cases, when property should be initialized once, initialization is easy and trivial.
Option 2 allows to control initialization flow (e.g., make lazy initialization). Initialization flow, in turn, depends from a property nature.
Upvotes: 0