I have an abstract class Parent and a derived class Child. I know that I can call Parent's constructor inside Child's constructor in the following way:
abstract class Parent
{
protected int i;
protected Parent(int i)
{
this.i = i;
}
}
class Child : Parent
{
public Child(int i) : base(i)
{
}
}
However, I don't want to pass some parameters to the Parent constructor right away. I would like to perform some calculations and then call Parent's constructor using the result of such calculation as input parameters. The code "would look" something like this:
public class Child : Parent
{
public Child(int i)
{
int calculation = i * 2; // Complicated operation
base(calculation); // This line will break
}
}
The second snippet is not valid C# code. Is there any way of postponing the call to Parent's constructor to mimic the sentiment expressed on the second code snippet?
This would do the same trick assuming u can access the properties directly
abstract class Parent
{
protected int i;
protected Parent()
{
//default constructor
}
}
class Child : Parent
{
public Child(int i)
{
Int calculation = i * 2
base.i = calculation
}
}
however if u cant do that because of restricted access to the properties my personal preference is to outsource the logic of the calculation in separate function and call the base class like following:
abstract class Parent
{
protected int i;
protected Parent(int i)
{
this.i = i;
}
}
class Child : Parent
{
public Child(int i) : base(Child.dosomework(i))
{
}
public static int dosomework(int i){
int calculation = i * 2
return calculation
}
}
abstract class Parent
{
protected int i;
protected Parent(int i)
{
this.i = i;
}
protected Parent(Func<int> param)
{
i = param();
}
}
class Child : Parent
{
public Child(int i) : base(() => i * 2)
{
}
}
Create a static method and use base(MyStaticMethod(params))
If you were allowed to call a base constructor in the child class in that way, you can face weird problems in your programs. Means that you can leave that instance in an inconsistent state because you could make a try-catch to handle some input-parameter errors and bypass the constructor. That is not the idea, imagine if you were allowed to create a Date in that way.
class MyDate : DateTime
{
public int(int year, int month, int day)
{
try
{
base(-1, -1, -1)
}
catch
{
}
}
}
The funny thing is that Java allows that with the super keyword.
The point of a constructor is to construct the instance, i.e. get it into a valid state. It should do that and nothing else. And if your class can exist without having i set already, then the act of setting i is not essential to its validity and therefore doesn't belong in a constructor.
Perhaps you don't want inheritance, you want composition.
class Inner
{
protected readonly int _i;
public Inner(int i)
{
_i = i;
}
}
class Outer
{
protected Inner _inner = null;
public Outer()
{
//Construct
}
public void SetI(int i)
{
_inner = new Inner(i); //Call constructor of Inner
}
}
Related
maybe my question is totally stupit but I'm trying to do my best.
All I want to do is to use a function/property of a parent element.
I have prepared a simple example with no sense:
class A
{
public List<B> myBs = new List<B>();
public int CountMyBs()
{
return myBs.Count;
}
}
class B
{
//here i would like to use "CountMyBs()"
}
Thank you!
Edit: I think I have to provide you some more information.
My user is able to drag a value to a canvas.
My canvas is in a list of a parent class.
Now my canvas wants to know if any other canvas in the list has already the same value.
My idea of realizing:
User does a drag --> Canvas gets an event --> Canvas ask parent class if any other Canvas has already the same value --> decide what to do.
I will post a mor detailed example tomorrow!
You need something like this:
class A : FrameworkElement
{
public int CountMyBs() {}
}
class B : FrameworkElement
{
public void Foo()
{
var parent = LogicalTreeHelper.GetParent(this) as A;
if (parent != null)
{
//here i would like to use "CountMyBs()"
parent.CountMyBs();
}
}
}
You can pass the instance of A through the constructor of B:
class B
{
private readonly A a;
public B(A a)
{
this.a = a;
}
public int Foo() //Example use
{
return 1 + a.CountMyBs();
}
}
class A
{
public List<B> myBs = new List<B>();
public A()
{
myBs.Add(new B(this)); //Pass the current A to B
}
public int CountMyBs()
{
return myBs.Count;
}
}
But it looks like a bad code smell to me. Unless you have a very specific use case for this, I'd avoid having a child class knowing its parent class only to access a list of itself.
You could simply call your Bs from A, with your method result as a parameter. Feels more natural. It could look like :
class A
{
public List<B> myBs = new List<B>();
public A()
{
var someB = new B();
myBs.Add(someB);
someB.Foo(CountMyBs());
}
public int CountMyBs()
{
return myBs.Count;
}
}
class B
{
public int Foo(int count) //Example use
{
return 1 + count;
}
}
I have next code
class Base
{
public virtual int Prop { get; set; }
}
class Derived : Base
{
public override int Prop { get { return 1; } }
}
//...
Derived obj = new Derived();
int some = obj.Prop; //expected
obj.Prop = 10; //oops it works
The fact that the last line should complile seems not to be so obvious at first sight. In my program I have a situation when overriding some auto-implemented property in a such way would be a solution. I understand that it's not a good approach. What kind of refactoring can I do to avoid such inheritance and to clean my code? Thanks
A derived class has to implement the same interface as its base class - having a public setter be inaccessible from a derived class would break polymorphism.
If Prop needs to be inaccessible to clients, but you need to be able to set its value from within the class itself, you could declare it as:
public virtual int Prop { get; protected set; }
There probably isn't a single answer to this question, as it depends on the model for your specific application. If some derived classes need to allow writes to this property, but others don't, you could either throw an exception on an invalid write and handle it at run time, or perhaps implement the property using a protected backing field and only a getter, and then add a derived class that provides a SetProp() method for those classes that need it.
public class Base
{
protected int prop;
public virtual int Prop { get { return prop; } }
}
public class WriteableBase : Base
{
public virtual void SetProp(int prop) { this.prop = prop; }
}
class Base
{
public virtual int Prop { get; set; }
}
class Derived : Base
{
public new int Prop { get { return 1; } private set {} }
}
The problem is that if you cast your Derived to Base, you can set the property anyway. If the Property relay on a field, it will be overwriten.
Ex.:
class Base
{
protected int fProp;
public virtual int Prop { get { return fProp; } set { fProp = value; } }
}
class Derived : Base
{
public Derived()
{
fProp = 1;
}
public new int Prop { get { return fProp; } private set {} }
}
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
//...
Derived obj = new Derived();
int some = obj.Prop; //expected
Base b = (Base)obj;
b.Prop = 10; //oops it works
Console.WriteLine(obj.Prop); =>it will show 10, not 1
Console.ReadKey();
}
}
}
A "better" approach to avoid this kind of problem is to avoid the use of a base class if you want to "change" something on a derived class. Or, put only the minimal content that must be implemente by ALL derived classes and let the derived classes implement any extra code that only they want.
Ex:
class Base
{
protected int fProp;
}
class Derived : Base
{
public Derived()
{
fProp = 1;
}
public int Prop { get { return fProp; } }
}
class Derived2 : Base
{
public int Prop { get { return fProp; } set { fProp = value; } }
}
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
//...
Derived obj = new Derived();
int some = obj.Prop; //expected
Base b = (Base)obj;
//obj.Prop = 10; Compilation error
Console.WriteLine(obj.Prop);
Derived2 obj2 = new Derived2();
obj2.Prop = 10;
Console.WriteLine(obj2.Prop);
Console.ReadKey();
}
}
}
Also, you could "encapsulate" your base class:
class Derived
{
protected Base fBase;
public Derived()
{
fBase = new Base;
}
//implement enything that you need to access from Base class
public int Prop { get { return 1; } }
}
But I find this last one too "expensive"... :)
I think it´s not possible to get compiler-error in this case. Imagine further you´d declare obj not as Derived but as Base = new Derived(), how should compiler know which property to infer. So all you can do is to throw an exception during runtime within the derived setter telling that setting this property isn´t allowed fir this type.
class Base
{
public virtual int Prop { get; protected set; }
}
class Derived : Base
{
public override int Prop {
get { return 1; }
protected set {throw NotSupportedException();}
}
}
When compiling, C# transforms the getter and setter to individual methods (get_Prop and set_Prop).
Your code only implements the get in the Derived class, and the setremains that of the base class.
If this is your desired behavior, I don't find it to be wrong.
If you are trying to hide the setter in the Derived class, there is no elegant way to do it, so throwing an NotSupportedException is a solution.
class Base
{
public virtual int Prop { get; set; }
}
class Derived : Base
{
public override int Prop { get { return 1; } set { throw new NotSupportedException();}}
}
I want to inherit from NHibernate's SqlClientBatchingBatcher class exactly like this (code taken from TooManyRowsAffectedException with encrypted triggers):
public class NonBatchingBatcherWithoutVerification : SqlClientBatchingBatcher
{
public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor) : base(connectionManager, interceptor)
{}
protected override void DoExecuteBatch(IDbCommand ps)
{
log.DebugFormat("Executing batch");
CheckReaders();
Prepare(currentBatch.BatchCommand);
if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
{
Factory.Settings.SqlStatementLogger.LogBatchCommand(currentBatchCommandsLog.ToString());
currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
}
int rowsAffected = currentBatch.ExecuteNonQuery();
// Removed the following line
//Expectations.VerifyOutcomeBatched(totalExpectedRowsAffected, rowsAffected);
currentBatch.Dispose();
totalExpectedRowsAffected = 0;
currentBatch = new SqlClientSqlCommandSet();
}
}
Just notice some of the members accessed in the method here (like currentBatch or totalExpectedRowsAffected).
Well, it turns out these members are actually private in the superclass of the current NHibernate 3.3 source. So how do I effectively inherit the class without copying the whole thing? This is the unmodified NHibernate code of the class by the way:
public class SqlClientBatchingBatcher : AbstractBatcher
{
private int _batchSize;
private int _totalExpectedRowsAffected;
private SqlClientSqlCommandSet _currentBatch;
private StringBuilder _currentBatchCommandsLog;
private readonly int _defaultTimeout;
public SqlClientBatchingBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
: base(connectionManager, interceptor)
{
_batchSize = Factory.Settings.AdoBatchSize;
_defaultTimeout = PropertiesHelper.GetInt32(Cfg.Environment.CommandTimeout, Cfg.Environment.Properties, -1);
_currentBatch = CreateConfiguredBatch();
//we always create this, because we need to deal with a scenario in which
//the user change the logging configuration at runtime. Trying to put this
//behind an if(log.IsDebugEnabled) will cause a null reference exception
//at that point.
_currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
}
public override int BatchSize
{
get { return _batchSize; }
set { _batchSize = value; }
}
protected override int CountOfStatementsInCurrentBatch
{
get { return _currentBatch.CountOfCommands; }
}
public override void AddToBatch(IExpectation expectation)
{
_totalExpectedRowsAffected += expectation.ExpectedRowCount;
IDbCommand batchUpdate = CurrentCommand;
Driver.AdjustCommand(batchUpdate);
string lineWithParameters = null;
var sqlStatementLogger = Factory.Settings.SqlStatementLogger;
if (sqlStatementLogger.IsDebugEnabled || Log.IsDebugEnabled)
{
lineWithParameters = sqlStatementLogger.GetCommandLineWithParameters(batchUpdate);
var formatStyle = sqlStatementLogger.DetermineActualStyle(FormatStyle.Basic);
lineWithParameters = formatStyle.Formatter.Format(lineWithParameters);
_currentBatchCommandsLog.Append("command ")
.Append(_currentBatch.CountOfCommands)
.Append(":")
.AppendLine(lineWithParameters);
}
if (Log.IsDebugEnabled)
{
Log.Debug("Adding to batch:" + lineWithParameters);
}
_currentBatch.Append((System.Data.SqlClient.SqlCommand) batchUpdate);
if (_currentBatch.CountOfCommands >= _batchSize)
{
ExecuteBatchWithTiming(batchUpdate);
}
}
protected override void DoExecuteBatch(IDbCommand ps)
{
Log.DebugFormat("Executing batch");
CheckReaders();
Prepare(_currentBatch.BatchCommand);
if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
{
Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
_currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
}
int rowsAffected;
try
{
rowsAffected = _currentBatch.ExecuteNonQuery();
}
catch (DbException e)
{
throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
}
Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowsAffected);
_currentBatch.Dispose();
_totalExpectedRowsAffected = 0;
_currentBatch = CreateConfiguredBatch();
}
private SqlClientSqlCommandSet CreateConfiguredBatch()
{
var result = new SqlClientSqlCommandSet();
if (_defaultTimeout > 0)
{
try
{
result.CommandTimeout = _defaultTimeout;
}
catch (Exception e)
{
if (Log.IsWarnEnabled)
{
Log.Warn(e.ToString());
}
}
}
return result;
}
}
Did I overlook something? Seems to a rather bad approach to copy the whole thing just to override all access to any private members. I just want to override one method!
There is only one way to legally access private members of your base class: put the derived class inside the base class:
class Base
{
private int x;
private class Derived : Base
{
private void M()
{
Console.WriteLine(this.x); // legal!
}
}
}
Of course, if you could put the class inside the base class then you could also rewrite the base class so that the members were protected.
That the original author made the members private is a hint to you that the class was not designed for you to muck around with that data.
If they're set as private, there's really nothing (short of using Reflection, which is ugly and certainly not always safe) that you can do.
Private members of a superclass cannot be accessed, bcause they are private. Encapsulation in OOP is there to prohibit this direct access and so ensure that objects function properly.
There might be properties to access the private members, These are the ones you can use to read from/write to private members. The properties will ensure that no harm to the object will be done.
You can access private fields, properties and methods of a parent class using reflection (for example, accessing a field as described here: Reflecting a private field from a base class)
This is not safe, however as the idea of private is that the library implementation could change and those private methods, fields and properties could change or disappear. If they change the implementation, an update could break your code.
That said, I've done it a few times myself. You just need to weigh the risk.
I was tackled by this issue for too many times so i decided to share and see what you guys think, lets look at the following (dumb) exemple:
public delegate void ToRun();
class Runner {
ToRun tr;
public Runner(ToRun f) {
tr=f;
}
public void run() {
tr();
}
}
class CountingRunner : Runner {
ToRun tr;
int i;
public CountingRunner(ToRun f) : base(f+=inc) {
i=0;
}
private static void inc() {
i++; //COMPILATION ERROR - i is not (and logically cannot be) static!
}
}
well, what i want to ask is:
Q1: why do base() parms have to be static?
Q2: what if, as in my exemple, we want to combine nonstatic fields or methods with the call to the base constructor? what is the most OOP way to do that?
Note : try not to give bandaid solutions like "just dont use the base c'tor", cause there might be more complex situation where using base is unavoidable, so im looking for a reasonable well designed solution for this.
Thanks!
Update:
my exemple was too easy to crack,therefore i feel like i havent learned enough, so lets try to give another (pretty dumb still) exemple:
public delegate int HashFunc<E>(E e);
public interface HashTable<E> {
void insert(E e);
bool isMember(E e);
}
class HashArray<E> : HashTable<E> where E : IComparable<E> {
private E[] a;
private bool[] taken;
public readonly int n;
public int size {
get { return n; }
}
HashFunc<E> hash;
public HashArray(int m , HashFunc<E> hash ) {
n=2*m;
a=new E[n];
taken=new bool[n];
for (int i=0 ; i<n ; i++) taken[i]=false;
this.hash=hash;
}
public void insert(E e) {
int index=hash(e),i;
for (i=index ; i<n && taken[i]!=false ; ++i) ;
if (i>=n)
for (i=0 ; i<index && taken[i]!=false ; ++i) ;
if (i>=index) return;
taken[i]=true;
a[i]=e;
}
public bool isMember(E e) {
int i=hash(e);
for ( ; i<n && taken[i]!=false && a[i].CompareTo(e)!=0 ; ++i );
if (i>=n || taken[i]==false) return false;
return true;
}
}
class HashArrayInt : HashArray<int> {
public HashArrayInt(int n) : base (n,HashFunc) {
}
public static int HashFunc(int i) {
return (i%n);// n is a non static field, every hash table has its own size!
}
}
in this exemple we are giving some weird implementation for an hash table where the hash function is unknown, and a special class for hash table of ints with predefined hash function, notice that here again we need to combine the non static size of the hashtable n and base c'tor...
Q1: why do base() parms have to be static?
They must be static because the instance hasn't been defined at the time of the constructor call (that definition was "in progress").
Q2: what if, as in my exemple, we want to combine nonstatic fields or methods with the call to the base constructor? what is the most OOP way to do that?
To OOP-way would is just simple method overrides.
class Runner
{
ToRun tr;
public Runner(ToRun f)
{
tr=f;
}
public virtual void Run()
{
tr();
}
}
class CountingRunner : Runner {
int i;
public CountingRunner(ToRun f) : base(f) {
i=0;
}
public override void Run() {
i++;
base.Run();
}
}
This is what you want:
class Runner {
protected event Action _toRun;
public Runner() {
}
public void Run() {
var r = _toRun;
if (r != null)
_toRun();
}
}
class CountingRunner : Runner {
int i;
public CountingRunner(Action f) : base() {
_toRun += f;
}
public void inc() {
i++;
}
}
EDIT
For your particular example with hash tables, this problem is solved by the design of the language. Just call GetHashCode() on the elements of your hashtable to determine their hashcode. You don't need implementations to pass a hashing function.
To answer your more general question of "How should I send functions manipulating instance data to the base class," you should either capture your instance variables in a lambda expression and send that to the base class, or consider a design in which the base class doesn't need access to the instance functions of its derived classes. I would go with the latter :)
One such design would be to have the function a pure virtual call in the base class. That would require derived classes to implement the virtual call in order to be instantiated. So here you would have a abstract int GetHashCode(E item) function in the base class, and just override it in your subclasses. Again, in this specific case the language does this for you with the virtual GetHashCode() function defined for all types.
Here is a non-abstract example (derived classes aren't required to override the hashing function).
class HashArray<E> : HashTable<E> where E : IComparable<E> {
private E[] a;
private bool[] taken;
public readonly int n;
public int size {
get { return n; }
}
public HashArray(int m) {
n=2*m;
a=new E[n];
taken=new bool[n];
for (int i=0 ; i<n ; i++) taken[i]=false;
}
public void insert(E e) {
int index= GetSpecialHashCode(e)%n;
int i;
for (i=index ; i<n && taken[i]!=false ; ++i) ;
if (i>=n)
for (i=0 ; i<index && taken[i]!=false ; ++i) ;
if (i>=index) return;
taken[i]=true;
a[i]=e;
}
public bool isMember(E e) {
int i= GetSpecialHashCode(e)%n;
for ( ; i<n && taken[i]!=false && a[i].CompareTo(e)!=0 ; ++i );
if (i>=n || taken[i]==false) return false;
return true;
}
protected virtual int GetSpecialHashCode(E item) {
return item.GetHashCode();
}
}
So you get a default hashcode generating function, but derived classes are also welcome to supply their own.
Regarding both Q1 and Q2, it's not that the parameters must be static, but rather the parameters must be accessible at the time they are invoked.
And base constructors are invoked prior to the local constructor, which is why you can't use this members as parameter for example, and why you shouldn't invoke virtual calls.
Not totally sure what the ultimate goal of that would be, but it does resemble a Decorator pattern.
For your last example, I think this could work:
class HashArrayInt : HashArray<int> {
public HashArrayInt(int n) : base (n,i => HashFunc(i,n)) {
}
private static int HashFunc(int i, int n) {
return (i%n);// n is a non static field, every hash table has its own size!
}
}
If not, you can do this:
class HashFuncProvider {
private int n;
public HashFuncProvider(int n){
this.n = n;
}
public int HashFunc(int i) {
return (i%n);
}
}
class HashArrayInt : HashArray<int> {
public HashArrayInt(int n) : base (n, new HashFuncProvider(n).HashFunc) {
}
}
I have a "meter" class. One property of "meter" is another class called "production".
I need to access to a property of meter class (power rating) from production class by reference. The powerRating is not known at the instantiation of Meter.
How can I do that?
public class Meter
{
private int _powerRating = 0;
private Production _production;
public Meter()
{
_production = new Production();
}
}
Store a reference to the meter instance as a member in Production:
public class Production {
//The other members, properties etc...
private Meter m;
Production(Meter m) {
this.m = m;
}
}
And then in the Meter-class:
public class Meter
{
private int _powerRating = 0;
private Production _production;
public Meter()
{
_production = new Production(this);
}
}
Also note that you need to implement an accessor method/property so that the Production class can actually access the powerRating member of the Meter class.
I wouldn't reference the parent directly in the child objects. In my opinion the childs shouldn't know anything about the parents. This will limits the flexibility!
I would solve this with events/handlers.
public class Meter
{
private int _powerRating = 0;
private Production _production;
public Meter()
{
_production = new Production();
_production.OnRequestPowerRating += new Func<int>(delegate { return _powerRating; });
_production.DoSomething();
}
}
public class Production
{
protected int RequestPowerRating()
{
if (OnRequestPowerRating == null)
throw new Exception("OnRequestPowerRating handler is not assigned");
return OnRequestPowerRating();
}
public void DoSomething()
{
int powerRating = RequestPowerRating();
Debug.WriteLine("The parents powerrating is :" + powerRating);
}
public Func<int> OnRequestPowerRating;
}
In this case I solved it with the Func<> generic, but can be done with 'normal' functions.
This why the child(Production) is totally independent from it's parent(Meter).
But! If there are too many events/handlers or you just want to pass a parent object, i would solve it with an interface:
public interface IMeter
{
int PowerRating { get; }
}
public class Meter : IMeter
{
private int _powerRating = 0;
private Production _production;
public Meter()
{
_production = new Production(this);
_production.DoSomething();
}
public int PowerRating { get { return _powerRating; } }
}
public class Production
{
private IMeter _meter;
public Production(IMeter meter)
{
_meter = meter;
}
public void DoSomething()
{
Debug.WriteLine("The parents powerrating is :" + _meter.PowerRating);
}
}
This looks pretty much the same as the solution mentions, but the interface could be defined in another assembly and can be implemented by more than 1 class.
Regards,
Jeroen van Langen.
You would need to add a property to your Production class and set it to point back at its parent, this doesn't exist by default.
Why not change the constructor on Production to let you pass in a reference at construction time:
public class Meter
{
private int _powerRating = 0;
private Production _production;
public Meter()
{
_production = new Production(this);
}
}
In the Production constructor you can assign this to a private field or a property. Then Production will always have access to is parent.
You could maybe add a method to your Production object called 'SetPowerRating(int)' which sets a property in Production, and call this in your Meter object before using the property in the Production object?
I would give the parent an ID, and store the parentID in the child object, so that you can pull information about the parent as needed without creating a parent-owns-child/child-owns-parent loop.
something like this:
public int PowerRating
{
get { return base.PowerRating; } // if power inherits from meter...
}