Need something like static inheritance in C# - c#

I'm having a small design issue and wanted to consult.
Lets say we have the following class hierarchy:
abstract class A
{
}
class B : A
{
}
class C: A
{
}
I want that both B and C have a certain field x so that it's value is different between the classes but shared among all instances of the same class (i.e: if b1, b2 are instances of B and c1,c2 instances of C then b1.x = b2.x and c1.x = c2.x and b1.x != c1.x).
Is there an elegant way to do this by taking advantage of the fact that both B, C derive from the same base class or do I have to create a static field x in both classes?
Thanks in advance.

You mean like this?
abstract class A
{
static Dictionary<Type, int> all_x;
protected int X {
get { return all_x[GetType()]; }
set { all_x[GetType()] = value; }
}
}
If it has to be a field so you can pass by reference:
abstract class A
{
class SharedType { int x; }
static Dictionary<Type, SharedType> all_shared;
protected SharedType Shared {
get
{
Type t = GetType();
SharedType result;
if (!all_shared.TryGetValue(t, out result) {
result = new SharedType();
all_shared.Add(t, result);
}
return result;
}
}
}
Also, we can improve performance by doing the lookup only once per instance:
abstract class A
{
class SharedType { int x; }
static Dictionary<Type, SharedType> all_shared;
protected SharedType Shared;
A() {
Type t = GetType();
if (!all_shared.TryGetValue(t, out Shared) {
Shared = new SharedType();
all_shared.Add(t, Shared);
}
}
}

What should those values be for the field x? If you need to specify that the value of x for A should be "a", the value of x for B should be "b" etc., then you will have to specify the values "a", "b", ... somewhere and then you mught as well just use:
abstract class A {
public static int x = 1; // Just using "int" as example.
}
class B : A {
public static int x = 2;
}
If you do not care what the values are (which type do you need then) but merely want the values to be "different", then instead of using fields you could use something like:
abstract class A {
public int X { get { return this.GetType().GetHashCode(); } }
}
This does not take hash collisions into account, but maybe it is useful anyway?
What is it you are trying to achieve?

To build on Ben Voigt's first answer, I think what you want for your base class is this:
public abstract class A
{
private static ConcurrentDictionary<Type, int> _typeIDs = new ConcurrentDictionary<Type, int>();
private static int _nextID = 1;
public int TypeID
{
get
{
return _typeIDs.GetOrAdd(this.GetType(), type => System.Threading.Interlocked.Increment(ref _nextID));
}
}
}

public abstract class A
{
public abstract int Value { get; }
}
public class B : A
{
public override int Value { get { return 1; } }
}
public class C : A
{
public override int Value { get { return 2; } }
}

The only way I know to do this is if you make class A a generic class, i.e. class A<T>. Then have class B implement a different type for the generic type than the generic type that Class C implements.
If you don't use generics, then I believe this is impossible in .NET.
Here is an example where lets say the value you were interested in was a data structure with members int Foo and string Bar. One derive class could implement the an identical structure (but different derived type) than the other - the two structures would implement the same interface.
interface IAvalue
{
int Foo { get; set;}
string Bar {get; set;}
}
struct BValue
: IAvalue
{
public int Foo { get; set; }
public string Bar { get; set; }
}
struct CValue
: IAvalue
{
public int Foo { get; set; }
public string Bar { get; set; }
}
abstract class A<T> where T : IAvalue
{
protected static T myValue;
}
class B : A<BValue>
{
static B()
{
myValue.Foo = 1;
myValue.Bar = "text1";
}
}
class C : A<CValue>
{
static C()
{
myValue.Foo = 2;
myValue.Bar = "text2";
}
}

You can use one .net feature: If you have static data members in a generic class, .net creates different instances of static data members for each generic type you use.
So, you can write:
public abstract class A<T> where T : A<T>
{
protected static int myVariable { get; set; }
}
And inherit your classes as:
public class B : A<B>
{
public B()
{
myVariable = 1;
}
public int GetVariable()
{
return myVariable;
}
}
public class C : A<C>
{
public C()
{
myVariable = 2;
}
public int GetVariable()
{
return myVariable;
}
}
Then every instance of B will have shared access to one instance of myVariable and every instance of C will have shared access to another.
So, if you add Set(int a) method:
public void Set(int a)
{
myVariable = a;
}
And run the following code:
static void Main(string[] args)
{
B b1 = new B();
C c1 = new C();
B b2 = new B();
C c2 = new C();
Console.Write("{0}; ", b1.GetVariable()); // 1
Console.Write("{0}; ", b2.GetVariable()); // 1
Console.Write("{0}; ", c1.GetVariable()); // 2
Console.Write("{0}; ", c2.GetVariable()); // 2
Console.WriteLine();
c2.Set(333);
Console.Write("{0}; ", b1.GetVariable()); // 1
Console.Write("{0}; ", b2.GetVariable()); // 1
Console.Write("{0}; ", c1.GetVariable()); // 333
Console.Write("{0}; ", c2.GetVariable()); // 333
Console.ReadLine();
}
You get: 1; 1; 2; 2;
1; 1; 333; 333; output.

I would suggest defining a static Dictionary<Type, Integer[]>, and having the base-class constructor call GetType() on itself and see if it's yet in the static dictionary. If not, create a new single-element array and store it in the dictionary. Otherwise grab the array from the dictionary and store it in an instance field. Then define a property which reads or writes element zero of the array. This approach will achieve the requested semantics for all derivatives and sub-derivatives of the class.

Related

Possible to declare an interface containing an extension?

As part of a testing library, I would like to define an interface which says 'this object knows how to initialize itself randomly'. If members of the randomly filled object are references, the random initialization should be capable of assigning null to these members.
If I was doing this for one class, the code could look like this
public class QWorker
{
double mxVal = 0;
public void fillRandomly(System.Random xRng)
{
mxVal = xRng.NextDouble();
}
}
public class QBoss
{
public QWorker mxWorker;
void fillRandomly(System.Random xRng)
{
if (xRng.Next() % 2 == 1)
x1 = null;
else
{
x1 = new QWorker();
x1.fillRandomly(xRng);
}
}
}
Now if QBoss had mulitple reference-type members, if/else would have to be done for every member. It would look ugly and could be cumbersome to maintain. To cimrcumvent, I came up with the following sample code:
public interface QIRandomizable<T> where T : new()
{
static void fillRandomly(this System.Random xThis, ref T xRef); // XXX
}
class QWorker : QIRandomizable<QWorker>
{
public double mxDouble;
}
public static class QWorkerExtensions
{
public static void fillRandomly(this System.Random xThis, ref QWorker xRef)
{
if ((xThis.Next() % 2) == 1)
xRef = null;
else
{
xRef = new QWorker();
xRef.mxDouble = xThis.NextDouble();
}
}
}
public class QBoss : QIRandomizable<QBoss>
{
public QWorker mx1;
public QWorker mx2;
public static void fillRandomly(this System.Random xThis, ref QBoss xRef)
{
xRef = new QBoss();
xThis.fillRandomly(ref xRef.mxMember1); // can be null
xThis.fillRandomly(ref xRef.mxMember2); // can be null
}
}
However this does not compile and the first problem is on line marked XXX - the static keyword does not belong there.
As a result, I would like to ask the following:
Is it possible to declare an interface with an extension inside?
If yes, what should I change?
If not, is there a different way how to accomplish what I want?
Any help is much appreciated,
Daniel
No, you cannot. That's because you can only declare instance-methods on an interface, and extension methods must be static.
You can try something like this:
public interface IDoesSomething
{
void fillRandomly(Random r);
}
public class QBoss
{
public double mx1 { get; set; }
public double mx2 { get; set; }
public int mx3 { get; set; }
public object refType { get; set; }
public void fillRandomly(Random r)
{
FillRandom(GetProps(this), this, r);
}
}
public static IEnumerable<PropertyInfo> GetProps(object blah)
{
return blah.GetType().GetProperties();
}
public static void FillRandom(IEnumerable<PropertyInfo> obj, object onObj, Random r)
{
Action<PropertyInfo, object> setVal = (prop, val) => { prop.SetValue(onObj, val); };
foreach (var o in obj)
{
if (!o.PropertyType.IsValueType)
{
if (r.Next() % 2 != 1)
{
var v = Activator.CreateInstance(o.PropertyType);
setVal(o, v);
var id = v as IDoesSomething;
if (id != null)
id.fillRandomly(r);
}
}
if (o.PropertyType == typeof(double))
setVal(o, r.NextDouble());
if (o.PropertyType == typeof(int))
setVal(o, (int)(r.NextDouble() * 100));
//etc, etc
}
}
Here, you decide what to do once, and set the properties. This currently only works for properties, not fields, so you might want to refactor it a little to take both FieldInfo and PropertyInfo
Testing it yields:
mx1 0.786868741170908
mx2 0.434705327001729
mx3 51
refType Object

Override function in base class

In the below example, I want to replace part of a calculation without having to re-implement the entire calculation in the derived sub classes.
class DummyCalcBase
{
public int changeable_part()
{
return 5;
}
public int common_calculation()
{
return 5 * changeable_part();
}
}
class DummyCalc : DummyCalcBase
{
public new int changeable_part()
{
return 10;
}
}
class Program
{
static void Main(string[] args)
{
int c = new DummyCalcBase().common_calculation();
Console.WriteLine("Base gives " + c.ToString());
int c2 = new DummyCalc().common_calculation();
Console.WriteLine("Calc gives " + c2.ToString());
}
}
This then gives output:
Base gives 25
Calc gives 25
What I would like is to get DummyCalc().common_calculation() to call the new changeable_part (and give the answer 50).
This would mean I don't have to copy and paste the same method into sub classes.
you can override method if it is virtual
class DummyCalcBase
{
public virtual int changeable_part()
{
return 5;
}
public int common_calculation()
{
return 5 * changeable_part();
}
}
class DummyCalc : DummyCalcBase
{
public override int changeable_part()
{
return 10;
}
}
methods with new keyword only hide methods of base class
if method is virtual, the following code will compute 50:
DummyCalcBase dummy = new DummyCalc();
int calc = dummy.common_calculation();
SO: new vs override difference
Mark the method in the base class as either virtual if you want to provide a default implementation that derived types can override, or abstract if you want to leave the implementation up to derived types.
Then simply override those methods in your derived types, and provide functionality as needed.
If your scenario is as simple as you describe here, go for the virtual method, with an override method in the sub-class. If your calculation is more complex, you should take a look at the strategy pattern: http://en.wikipedia.org/wiki/Strategy_pattern
Your code will than look something like this:
public interface IStrategy
{
int getValue();
}
public class Context
{
private readonly IStrategy strategy;
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public int common_calculation()
{
return 5 * strategy.getValue();
}
}
public class FiveStrategy : IStrategy
{
public int getValue()
{
return 5;
}
}
public class TenStrategy : IStrategy
{
public int getValue()
{
return 10;
}
}
internal class Program
{
public static void Main(string[] args)
{
var context5 = new Context(new FiveStrategy());
Console.WriteLine(context5.common_calculation());
var context10 = new Context(new TenStrategy());
Console.WriteLine(context10.common_calculation());
Console.ReadLine();
}
}

Cloning a method in c#

Suppose I have a class A:
class A
{
void b() {...}
}
and a class B:
class B
{
A m;
}
This way, if I write B x, I can call x.m.b().
What I need is to dynamically create a method b() inside the B class, so I could use it as x.b() (of course, the results from calls x.m.b() and x.b() should be the same).
How can I do it?
There is one generic solution (where you won't have to f.e create delegates for every method from A you want). Unfortunately, It won't be a strongly-typed one. If you want so, please see other answers.
class A
{
public int B()
{
return 1;
}
}
class B : DynamicObject
{
private readonly A m = new A();
private static readonly Lazy<IEnumerable<MethodInfo>> AMethods =
new Lazy<IEnumerable<MethodInfo>>(() =>
{
var type = typeof (A);
return type.GetMethods(
BindingFlags.Instance |
BindingFlags.Public);
});
public override bool TryInvokeMember(
InvokeMemberBinder binder,
object[] args,
out object result)
{
if (base.TryInvokeMember(binder, args, out result))
{
return true;
}
var methods = AMethods.Value;
var method = methods.SingleOrDefault(mth => mth.Name == binder.Name);
// TODO: additional match (arguments type to handle overloads)
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(this.m, args);
return true;
}
public int OtherBMethods()
{
return 2;
}
}
Usage:
var b = new B();
int result = ((dynamic)b).B();
int other = b.OtherBMethods();
or
dynamic b = new B();
int result = b.B();
int other = b.OtherBMethods();
You could do this with delegates, in modern C# this could look like this
public class A
{
public void b() {...}
}
public class B
{
private A m = new A();
public Action b = ()=>m.b();
}
public void Main()
{
new B().b(); // This now invokes your delegates that invokes the b method on it's internal m object
}
Could also just do it with classical methods and simply expose a b method that does the exact same thing, don't see anything special / hard here? If you're trying to accomplish something else you need to clarify your question, like if you want to automate this there are easy compile time (T4 text templates) or at runtime (generating dynamic proxies).
What you are going to do is implement Decorator pattern in C#.
GoF defines Decorator pattern as "Attach additional responsibilities
to an object dynamically. Decorators provide a flexible alternative to
subclassing for extending functionality.
I would like to recommend look throught this article "Understanding and Implementing Decorator Pattern in C#".
I have created a simple example of the Decorator pattern implementation when you decorate Concrete with A and B functionality.
interface IDecorator
{
void Print();
}
class Concrete : IDecorator
{
public void Print()
{
Console.WriteLine("-> Concrete");
}
}
class A : IDecorator
{
IDecorator decorator;
public A(IDecorator decorator)
{
this.decorator = decorator;
}
public void Print()
{
decorator.Print();
Console.WriteLine("-> A");
}
}
class B : IDecorator
{
IDecorator decorator;
public B(IDecorator decorator)
{
this.decorator = decorator;
}
public void Print()
{
decorator.Print();
Console.WriteLine("-> B");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("concrete object that should be decorated");
var concrete = new Concrete();
concrete.Print();
Console.WriteLine("let's decorate this object with A decorator");
var decoratedWithA = new A(concrete);
decoratedWithA.Print();
Console.WriteLine("let's decorate this object with B decorator");
var decoratedWithB = new B(concrete);
decoratedWithB.Print();
Console.WriteLine("let's decorate concrete with A and B");
var decoratedWithAB = new B(new A(concrete));
decoratedWithAB.Print();
}
}
I have an abstract A class and classes A1 : A, A2 : A, A3 : A. Then i
also have a method named c(). I want to create classes
A1_with_c_method, A2_with_c_method, A3_with_c_methos while leaving A1,
A2 and A3 unharmed. What is the best way to do this? – h8red
You could do something like this:
abstract class A
{
}
class A1 : A
{
}
class A2 : A
{
}
class A3 : A
{
}
#region Not a good idea, because too many classes
class A1_with_c : A1
{
public void c() { }
}
class A2_with_c : A2
{
public void c() { }
}
class A3_with_c : A3
{
public void c() { }
}
#endregion
// Decorate A with the c() method
class BaseDecorator
{
public A Instance { get; private set; }
public BaseDecorator(A instance)
{
Instance = instance;
}
public virtual void c()
{
// do something with instance
}
}
class Decorator : BaseDecorator
{
BaseDecorator decorator;
public Decorator(BaseDecorator decorator)
: base(decorator.Instance)
{
this.decorator = decorator;
}
public override void c()
{
Console.WriteLine("Ok");
}
}
class Program
{
static void Main(string[] args)
{
// not good
new A1_with_c().c();
new A2_with_c().c();
new A3_with_c().c();
// better
var a_with_c = new BaseDecorator(new A1());
a_with_c.c();
// Let's decorate with something interesting
new Decorator(a_with_c).c();
}
}
I agree with the comments that this really seems odd and I'm wondering why you would ever want to do this but here is a possibility for you.
interface IHasMethodb
{
void b();
}
class A : IHasMethodb
{
public void b() { ... }
}
class B : IHasMethodb
{
A m;
public void b() { return m.b(); }
}
Is this what you're trying to do?
It seems like you either want the concept of wrapping a method, which in your example is as simple as:
class A {
public void b() { ... }
}
class B {
A m;
public void b() { m.b(); }
}
Allowing you to:
B x = new B();
x.b();
If you want to be able to "dynamically create" the method then this might be more applicable, using an Action<T> to allow you to do whatever you like with the A instance, without actually exposing it:
class A {
public void b() {...}
}
class B {
A m;
public Action<A> doSomethingWithA;
public void b() {
if (doSomethingWithA != null)
doSomethingWithA(m);
}
}
Then you can:
B x = new B();
x.doSomethingWithA = a => a.b();
x.b();

Shared Data Members that are unique to inheritance branches?

I have the situation below. Is there a simple way to design this so that the data member sample is shared among all instantiations of ChildClass1 and a separate instance of it is shared with all instances of ChildClass2?
abstract class BaseClass{
int sample = 0;
}
class ChildClass1: BaseClass{
}
class ChildClass2: BaseClass{
}
I'm hoping to produce the following
ChildClass1 a = new ChildClass1();
ChildClass1 b = new ChildClass1();
ChildClass2 c = new ChildClass2();
a.sample = 10;
//a.sample = 10, b.sample = 10, c.sample = 0
Maybe this does, what you want:
public abstract class BaseClass
{
public abstract int Sample { get; set; }
}
public class ChildClass1 : BaseClass
{
private static int mSample = 0;
public override int Sample
{
get { return mSample; }
set { mSample = value; }
}
}
public class ChildClass2 : BaseClass
{
private static int mSample = 0;
public override int Sample
{
get { return mSample; }
set { mSample = value; }
}
}
class Program
{
static void Main(string[] args)
{
var a = new ChildClass1();
var b = new ChildClass1();
var c = new ChildClass2();
a.Sample = 10;
Console.WriteLine(a.Sample); // 10
Console.WriteLine(b.Sample); // 10
Console.WriteLine(c.Sample); // 0
}
}
As I said in my comment, I think there is an inherent flaw in your design, but for the sake of providing an answer, you could achieve it like this:
abstract class BaseClass<TDERIVED>
{
private static Dictionary<Type, int> sampleDictionary_ = new Dictionary<Type, int>();
public BaseClass()
{
} // eo ctor
public int Sample
{
get
{
return sampleDictionary_.ContainsKey(typeof(TDERIVED)) ? sampleDictionary_[typeof(TDERIVED)] : 0;
}
set
{
sampleDictionary_[typeof(TDERIVED)] = value;
}
}
}
class ChildClass1 : BaseClass<ChildClass1>
{
}
class ChildClass2 : BaseClass<ChildClass2>
{
}
This has the added advantage that if you add any other Child classes, they will get their own version of the response. Note that this is not thread-safe, and so if you do choose this solution and want to use it in a multi-threaded environment, you might want to put some thread-safety code in place.
You may want to look into the singleton pattern.
Create a class as a singleton to hold the shared data. Then have all three classes reference the singleton.

Call one constructor from another

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.

Categories

Resources