How to prevent multiple Initialization of property from derived classes - c#

The code below is a short "summary" of my real project that contain only the relevant parts to understand my question. (and don`t want to ruin someones day with the original code).
imagine you have 4 classes: Division, Branch, Department and Team. every class inherits base class in that order.
The final goal: return one division object that holds List of 7 Branches, each Branch holds List of 7 Departments and each Department holds List of 7 Teams.
for example i will be able to reach from outside to every class instance:
division d = new division();
d.CreateDivisionStructure();
int Example = d.ListOfBranches[5].ListOfDepartments[4].ListOfTeam[3].SomeIntegerProperty;
(the original code has that lists, override functions, properties etc..)
the problem: imagine that protected string _myVar in the code below is a Datatable that needs to initialized via myVarproperty with heavy resource consuming SQL query. hence, my wish is to initialize protected string _myVar only one time for all the creation of the "division units structure". in the code below protected string _myVar will be null 64 times and will be initialized 64 times (for my understanding 7 times for each unit and one time for each base() call).
how can i achieve that?
i tried quite a lot other ways but could not solve that. I would appreciate any help, different way of thinking or advice.
class Program
{
static void Main(string[] args)
{
division d = new division();
d.CreateDivisionStructure();
Console.ReadLine();
}
}
class division
{
private static int CountHowManyTimesMyVarWasInitilized = 0;
public division()
{
}
protected string _myVar;
public string myVar
{
get
{
if (_myVar == null)
{
CountHowManyTimesMyVarWasInitilized++;
Console.WriteLine(CountHowManyTimesMyVarWasInitilized);
_myVar = "now myVar is not null";
return _myVar;
}
else
{ return _myVar; }
}
set { _myVar = value; }
}
public void CreateDivisionStructure()
{
Console.WriteLine(myVar);
for (int i = 0; i < 7; i++)
{
Branch b = new Branch(7);
}
}
}
class Branch : division
{
public Branch(bool dImDerivedClass)
{
// constructor for department to prevent recursive stackoverflow if base of department will call the empty constructor
}
public Branch(int NumberOfBranches)
{
Console.WriteLine(myVar);
Department d = new Department(7);
}
}
class Department : Branch
{
public Department(bool ImDerivedClass) : base(true)
{
// constructor for team to prevent recursive stackoverflow if base of Team will call the empty constructor
}
public Department(int numberOfDep) : base(true)
{
for (int i = 0; i < numberOfDep; i++)
{
Console.WriteLine(myVar);
Team t = new Team(7);
}
}
}
class Team : Department
{
public Team(int numberOfTeams) : base(true)
{
for (int i = 0; i < numberOfTeams; i++)
{
Console.WriteLine(myVar);
}
}
}
}

This is likely a good use of the Lazy<T> class, used in a static variable so there is only a single copy for the process. It will run the Func you give it once to initialize during the first access of the variable.
https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx
However, based on your class structure I'm not sure if it is the best approach. What is the purpose for the hierarchy of Branch : division and Department : Branch. Is the Branch a Division? If you are trying to share common properties as to not code them over again, I would suggest creating a common class that can hold those variables that Branch, Division, and Department can inherit from.

You can use a static variable / static constructor in the lowest class in the hierarchy. The static constructor will only be called once.

A simple solution is to use a "control" variable.
I'm sure you can improve your design and avoid this problem but I don't have time to check it now..
using System;
namespace Program
{
internal class Program
{
private static void Main(string[] args)
{
division d = new division();
d.CreateDivisionStructure();
Console.ReadLine();
}
}
internal class division
{
private static int CountHowManyTimesMyVarWasInitilized = 0;
public division()
{
}
protected string _myVar;
private bool _isReadyForInitialization;
public string myVar
{
get
{
if (!_isReadyForInitialization)
return null;
if (_myVar == null)
{
CountHowManyTimesMyVarWasInitilized++;
Console.WriteLine(CountHowManyTimesMyVarWasInitilized);
_myVar = "now myVar is not null";
return _myVar;
}
else
{ return _myVar; }
}
set { _myVar = value; }
}
public void CreateDivisionStructure()
{
// now _myVar is spposed to be initilized to all dirved clasess isnt is?
Console.WriteLine(myVar);
for (int i = 0; i < 7; i++)
{
Branch b = new Branch(7);
}
_isReadyForInitialization = true;
Console.WriteLine(myVar);
}
}
internal class Branch : division
{
public Branch(bool dImDerivedClass)
{
// constructor for department to prevent recursive stackoverflow if base of department will call the empty constructor
}
public Branch(int NumberOfBranches)
{
Console.WriteLine(myVar);
Department d = new Department(7);
}
}
internal class Department : Branch
{
public Department(bool ImDerivedClass) : base(true)
{
// constructor for team to prevent recursive stackoverflow if base of Team will call the empty constructor
}
public Department(int numberOfDep) : base(true)
{
for (int i = 0; i < numberOfDep; i++)
{
Console.WriteLine(myVar);
Team t = new Team(7);
}
}
}
internal class Team : Department
{
public Team():base(false)
{
}
public Team(int numberOfTeams) : base(true)
{
for (int i = 0; i < numberOfTeams; i++)
{
Console.WriteLine(myVar);
}
}
}
}

Related

C# constructors sharing code and then referencing properties already set [duplicate]

I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.

C#: Calling parent (Base) constructor from child's constructor body

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
}
}

NInject 3 leaks (there's a sample project), is it possible to force removal of objects?

I created a sample project to model what I faced in my real project.
The problem is that when I query some external data in a cycle (in the real life my project queries windows to find match(es), and stops querying on success or on timeout expiration). It seems to me that NInject does not dispose created objects and consider the cycle as one long call.
How to work around this situation? Maybe, cut out the code that fills list and put it into another class? Or simply, could you make my sample project better?
The link on Github or its code below:
public interface IMyObj : IDisposable
{
string Name { get; set; }
}
public class MyObj : IMyObj
{
public virtual string Name { get; set; }
public virtual void Dispose()
{
Name = string.Empty;
GC.SuppressFinalize(this);
}
}
public class NjModule : NinjectModule
{
public override void Load()
{
Bind<IMyObj>()
.To<MyObj>()
.InCallScope();
Bind<Requester>()
.ToSelf()
.InSingletonScope();
}
}
public class Requester
{
public List<IMyObj> RequestObjects()
{
List<IMyObj> list = new List<IMyObj>();
for(int i = 0; i < 10; i++) {
var myObj = Program.Kernel.Get<IMyObj>();
myObj.Name = "abcdefghijklmnopqrstuvwxyz";
list.Add(myObj);
}
return list;
}
}
class Program
{
public static IKernel Kernel;
public static void Main(string[] args)
{
Console.WriteLine("Hello NInject!");
// TODO: Implement Functionality Here
Kernel = new StandardKernel(new NjModule());
Kernel.Settings.ActivationCacheDisabled = true;
var requester = Kernel.Get<Requester>();
for (int i = 0; i < 100000000; i++) {
List<IMyObj> list =
requester.RequestObjects();
foreach (MyObj listItem in list) {
listItem.Dispose();
}
list.Clear();
list = null;
}
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
I fixed the problem with memory by using ChildKernel. At the moment, I can't say anything about performance, however the memory leak is definitely fixed: the project started at 10MB and works on 15-25MB.
Anyway, I'd be glad to consider other alternatives to my solution if you, the stackoverflowers, have such.
My solution is here (Github) and the below:
public interface IMyObj : IDisposable
{
string Name { get; set; }
}
public class MyObj : IMyObj
{
public virtual string Name { get; set; }
public virtual void Dispose()
{
Name = string.Empty;
GC.SuppressFinalize(this);
}
}
public class NjModule : NinjectModule
{
public override void Load()
{
Bind<Requester>()
.ToSelf()
.InSingletonScope();
Bind<IChildKernel>().ToSelf().InSingletonScope();
}
}
public class NjChildKernelModule : NinjectModule
{
public override void Load()
{
Bind<IMyObj>()
.To<MyObj>()
.InCallScope();
}
}
public class Requester
{
public List<IMyObj> RequestObjects(IChildKernel childKernel)
{
List<IMyObj> list = new List<IMyObj>();
for(int i = 0; i < 10; i++) {
var myObj = childKernel.Get<IMyObj>();
myObj.Name = "abcdefghijklmnopqrstuvwxyz";
list.Add(myObj);
}
return list;
}
}
class Program
{
public static IKernel Kernel;
public static void Main(string[] args)
{
Console.WriteLine("Hello NInject!");
// TODO: Implement Functionality Here
Kernel = new StandardKernel(new NjModule());
Kernel.Settings.ActivationCacheDisabled = true;
var requester = Kernel.Get<Requester>();
for (int i = 0; i < 100000000; i++) {
var childKernel = new ChildKernel(Kernel, new NjChildKernelModule());
childKernel.Settings.ActivationCacheDisabled = true;
List<IMyObj> list =
requester.RequestObjects(childKernel);
foreach (MyObj listItem in list) {
listItem.Dispose();
}
list.Clear();
list = null;
childKernel.Dispose();
}
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
If think there is a misconception here.
I think InCallScope is not doing what you think it is. Have a look at the following integration test for InCallScope:
this.kernel.Bind<Parent>().ToSelf();
this.kernel.Bind<Child>().ToSelf().InCallScope();
this.kernel.Bind<IGrandChild>().To<GrandChild>().InCallScope();
var parent1 = this.kernel.Get<Parent>();
var parent2 = this.kernel.Get<Parent>();
parent1.Dispose();
parent1.FirstChild.Should().BeSameAs(parent1.SecondChild);
parent1.GrandChild.Should().BeSameAs(parent1.FirstChild.GrandChild);
parent1.FirstChild.Should().NotBeSameAs(parent2.FirstChild);
parent1.GrandChild.Should().NotBeSameAs(parent2.GrandChild);
parent1.FirstChild.IsDisposed.Should().BeTrue();
parent1.FirstChild.GrandChild.IsDisposed.Should().BeTrue();
parent2.FirstChild.IsDisposed.Should().BeFalse();
parent2.FirstChild.GrandChild.IsDisposed.Should().BeFalse();
parent2.Dispose();
parent2.FirstChild.IsDisposed.Should().BeTrue();
parent2.FirstChild.GrandChild.IsDisposed.Should().BeTrue();
(Source: https://github.com/ninject/ninject.extensions.namedscope/blob/master/src/Ninject.Extensions.NamedScope.Test/NamedScopeIntegrationTest.cs)
As you can see the IChild is instantiated in the scope of Parent. IChild is disposed as soon as Parent is disposed.
In your example, Requester is bound InSingletonScope. Everything which is instantiated for / by Requester in its InChildScope will only be disposed once Requester is disposed.
However, since you don't seem to be using ContextPreservation in your original Requester there is actually not even a scope for your IMyObj.
How would you like it to work?

Difficulty to combine the use of base constructors and nonstatic fields

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) {
}
}

How to access to the parent object in c#

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...
}

Categories