C# Delegates in Abstract and Subclass - c#

I am programming a Programme for Vacations Control for Companies (only to learn, not serious). Now I have a Abstract Class called Employee. and 4 stages of Employees.
EveryOne has it own class:
NormalWorker
SubjectAreaLeader
ChefHumanResourceOfficer
CEO
The Normal Worker can ask for Vacations, the SAL can say ok or deny the Request. If he says ok it will go to the CHRO. He can veto it or pass it. The CEO is the last Instance who can veto it.
All classes inherits the Abstract Class. The Abstract Class has a delegate called
public delegate void applyVacations(Vacation what_vacations, bool pass_or_deny)
All Subclasses have a Method
void apply(Vacation what_vacation, bool pass_or_deny)
except of the NormalWorker. And the Constructors of the subclasses shall push this apply Method to the delegate.
passing the vacation request is final for all Instances.
Example:
namespace ex
{
public abstract class A
{
public delegate void foo();
public A()
{ }
}
class B : A
{
public B()
{
A.foo = childfoo; // Does not work
}
public void childfoo()
{/* Do something*/}
}
}
Greetings

You need to create a variable of type foo and then assign childfoo to it, like so:
private foo _handler;
public B()
{
// Assign our handler for the foo delegate.
_handler = childfoo;
// Now we can call it.
_handler();
}

foo is a delegate so it's a type
in B constructor you should write
foo handler = childfoo;
then you can call handler()
namespace ex
{
public abstract class A
{
public delegate void foo();
public A()
{ }
}
class B : A
{
private foo handler;
public B()
{
handler = childfoo;
}
public void callHandlerHere()
{
handler();
}
public void childfoo()
{/* Do something*/}
}
}
this is for exemple purpose of course
B b = new B();
b.callHandlerHere() // all object inheriting A can habe a callHandlerHere function for exemple

Related

Multilevel Inheritance - Invoke Child Level New Method

In the below program, since new keyword is used in the derived class, I am expecting the output "C" but am getting the output as "A". Can some one please explain the reason behind this?
Also, I would like to know how to invoke Foo method declared in the class C.
class A
{
public void Foo()
{
Console.Write("A");
}
}
class B : A
{
new void Foo()
{
Console.Write("B");
}
}
class C : B
{
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo();
}
C.Foo() has no visibility on the private Foo you new'ed up inside C - it will call the public derived Foo from A.
class C : B
{
public void Test()
{
// this has visibility on the private new'ed up method and can call it
this.Foo();
}
// this is just a private method - it does NOT shadow the public one
// "new" does nothing valuable here
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo(); // calls the public visible derived A.Foo
c.Test(); // this will call the "new"ed up C.Foo()
}
Output:
AC
You can call private methods only from inside the class they belong to - not from the outside (unless you put the call to the private one inside a public method - see Test).
Most of the time new-ing up a method (to me) is a code smell.
The keyword new in this context prevents inheritance, i.e., it hides the inherited methods instead of providing a new implementation of them. There are only rare situations where you want to do this. Mainly for static members, since those can't be overridden.
The right way to inherit and possibly override methods is to make them virtual:
class A
{
public virtual void Foo()
{
Console.Write("A");
}
}
class B : A
{
public override void Foo()
{
Console.Write("B");
}
}
class C : B
{
public override void Foo()
{
Console.Write("C");
}
}
Now, your test will work as expected. It will even work if you assign the new C to variable typed as A:
A a = new C();
a.Foo(); // Prints: C
That being said, your Foo methods in B and C don't have a public modifier and are thus private. I.e., you can only access A.Foo, which is public, from the outside.

Passing child method to base constructor

I have a base class that implements some logic and eventually calls an Action which was passed to the contructor.
public class BaseClass
{
private Action action;
public BaseClass(Action someAction)
{
action += someAction;
}
private void doStuff()
{
action();
}
}
Now I want to derive some child classes that implement some specific logic. In these child classes I have a method for that logic and my attempt was to pass this method to the base constructor. But this result in a compiler error CS0120: An object reference is required for the nonstatic field, method, or property 'member'.
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i)
: base(doSpecificStuff) // <-- compiler error CS0120 here
{
b = i;
}
private void doSpecificStuff()
{
// do something depending on b
}
}
I don't quite get why it fails at that point. Is it because the base constructor gets called first which means when calling it I do not have an instance of the child class (including the child's method)?
But why does the compiler asks for a reference to a nonstatic field? Actually I don't see anything static here. Is there a way to get a reference to doSpecificStuff at that point? this.doSpecificStuff does not work, resulting in CS0027: Keyword 'this' is not available in the current context.
Any suggestions for a better design?
This is exactly where object-oriented-design (OOP) and one of its principles, Polymorphism, comes in place, and what it was designed for.
By making doStuff virtual in the base class, we can override the method in the specific class and customize its behavior.
public class BaseClass
{
private Action? action;
public BaseClass(Action someAction)
{
action += someAction;
}
protected BaseClass()
{
}
protected virtual void doStuff()
{
action?.Invoke();
}
}
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i)
{
b = i;
}
protected override void doStuff()
{
// do something depending on b
}
}
I don't quite get why it fails at that point. Is it because the base constructor gets called first which means when calling it I do not have an instance of the child class (including the child's method)?
Sort of. There is actually an instance of the child class (the object is created immediately of the "right" type) but you can't refer to anything specific to the instance in the constructor initializer.
From section 15.11.2 of the draft C# 6 spec:
An instance constructor initializer cannot access the instance being created.
The best way of handling this really depends on the broader context. For example, you could accept a Func<BaseClass, Action> instead and cast:
public class BaseClass
{
private Action action;
public BaseClass(Func<BaseClass, Action> actionProvider)
{
action += actionProvider(this);
}
private void doStuff()
{
action();
}
}
... then:
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i)
: base(x => ((SpecificClass) x).doSpecificStuff)
{
b = i;
}
private void doSpecificStuff()
{
// do something depending on b
}
}
That's a bit tortuous though. If the action is always expected to be a method in the derived class, an option would be to create an abstract method in the base class and just override it in the derived class instead.
The error message means that the compiler is expecting this:
private static void doSpecificStuff()
{
// do something depending on b
}
Why? because when you call your action in doStuff, C# has no way to now that doSpecificStuff has to be called on the current (this) instance.
To compile, you would have to do something like this :
public class BaseClass
{
private Action action;
public BaseClass(Action<BaseClass> someAction)
{
action += () => someAction(this);
}
private void doStuff()
{
action();
}
}
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i): base(x => ((SpecificClass)x).doSpecificStuff()) // <-- compiler error CS0210 here
{
b = i;
}
private void doSpecificStuff()
{
// do something depending on b
}
}
I do not know exactly why you came up with this approach but why not just us inheritance? (Again, there might be some specific need I'm not aware of here, I'm just mentioning this for the record to post an answer as complete as possible) For instance:
public class BaseClass
{
public BaseClass()
{
}
protected virtual void doStuff()
{
// Doing stuff...
}
}
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i): base()
{
b = i;
}
protected override void doStuff()
{
// do something depending on b
base.doStuff()// if needed...
}
}

Polymophism in C#, how to turn parent object into a child object in a method?

public class Program
{
public static void Main()
{
var type = new C().getType();
type.Foo();
}
public class A
{
public void Stop()
{
// do something
}
}
public class B : A
{
public void Foo()
{
Console.WriteLine("Foo");
}
}
public class D : A
{
public void Bar()
{
Console.WriteLine("Bar");
}
}
public class C
{
public A getType()
{
if (some condition)
return new B();
if (some condition)
return new D();
return A();
}
}
}
-EDIT-
I updated the code, so now we have two child classes B and D, both have different methods inside them, however since they inherit A, they at least both have access to Stop() method. The problem with making an abstract method Foo() and Bar() inside the parent class A is that, B should not have access to Bar() and D should not have access to Foo(), but by making an abstract method they will need to implement them both.
I know that I can check the type of the returned object inside Main() method and then cast it to that type. But this won't be convenient as in the future I will have more descendants of A.
Is it in my situation ok, to use dynamic? Because that would solve the problem and would be very convenient.
public class C
{
public dynamic getType()
{
if (some condition)
return new B();
if (some condition)
return new D();
return A();
}
}
You almost had it right:
public class Program
{
public static void Main()
{
var type = new C().getType();
type.Foo();
}
public abstract class A
{
public abstract void Foo();
}
public class B : A
{
public override void Foo()
{
Console.WriteLine("Foo");
}
}
public class C
{
public A getType()
{
return new B();
}
}
}
You need a Foo method in A that B can override. I have made A.Foo abstract, which means we do not have to define a base implementation of A.Foo. The A class is declared abstract to prevent someone trying to create an instance of it.
If you want derived classes to inherit a base implementation of Foo from A, then declare Foo as virtual in A. So in the following example, class B overrides the base Foo, whereas class C inherits the base Foo:
public class Program
{
public static void Main()
{
A a1 = new B();
a1.Foo(); // Outputs "B.Foo".
A a2 = new C();
a2.Foo(); // Outputs "A.Foo".
}
public abstract class A
{
public virtual void Foo()
{
Console.WriteLine("A.Foo");
}
}
public class B : A
{
public override void Foo()
{
Console.WriteLine("B.Foo");
}
}
public class C : A
{
}
}
You are confusing the type of a variable and the type of the runtime object it will be pointing to (given its a reference type, with value types, there is no such distinction).
When you declare a variable, you are defining the type of the variable:
Foo a = ... //a is of type Foo at compile time.
What you assign to that variable doesn't matter at all (unless you are using implicitly typed variables with var)
But given the following code:
object o = new Foo();
Now you can see the diferrence; the variable o is of type object but the runtime object it will be pointing to is of type string.
In your question you are asking why you cant do the following:
var stringLength = o.Length; //o is a string isn't it?
Why? Isn't o really a string. Yes, but that information is only availabe at runtime, the compiler knows nothing of what will happen at runtime, it only knows that o is of type object and object has no Length property. The only thing the compiler will make sure of is that the types are compatible; it will let you assign a Giraffe to an Animal typed variable but it won't let you assing a Car.
If you've got this clear, then you'll understando why this doesn't make sense:
But I did explicitly return B inside getType() method, why does it not have access to Foo()?
Because the method getType return type is A not B, not C and not D.

How to prevent calling constructor of one class while having access to its member functions in C#?

I have a class A, and a class AStore. My requirement is to prevent all other methods from initializing an instance of class A, which they should get an instance from AStore. In addition, I also need to access the member functions of A from the instance.
Factory pattern is not suitable for this problem as the constructor of A is still public. Ideally, it should throw compilation error when calling the constructor of class A while having access to its member functions.
Can I get C# solutions to this?
For restricting others to create an instance of class A you can use a private constructor and a static factory method to get the instance of that class.
public class A
{
private A(){}
public static A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
To enforce instance creation of A only via Astore you can use protected modifier and derive AStore from A. That way, only AStore will have access to its protected members like 'constructor' or 'factory method':
public class Astore : A
{
public A GetInstanceOfA()
{
return base.GetInstance();
}
}
public class A
{
protected A() { }
protected A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
//Usage
public class ConsumerClass
{
public void Test()
{
var a = new A(); // Compile error
a = new Astore().GetInstanceOfA();
a.MemberFunctionOfA();
}
}
But there're still chances that another class say 'UnWantedStore' can derive from A and serve instance of A.
Another approach is moving AStore and A classes to the dedicated project and make constructor of A class internal.
// Project A
namespace ProjectA
{
public class A
{
public int PropertyOne { get; set; }
public string PropertyTwo { get; set; }
internal A() {}
}
public class AStore
{
public A CreateA()
{
//internal constructor can be used
return A();
}
}
}
// Project ConsumerOfA
namespace ConsumerOfA
{
public static void UseA()
{
var store = new AStore();
var instanceOfA = store.CreateA();
// have access to the A's public members
}
}
With this approach you will get perfect encapsulation you trying to achive.
Abstract classes to the rescue!
Indeed, there's yet another possible approach! I've never used it but it might work in your scenario. See the following code sample:
public abstract class A
{
public string Text { get; set; }
public string SayHello() => "hello world!";
}
public class AStore
{
private class AInternal : A {}
public void DoStuff()
{
A a = new AInternal();
a.Text = "whatever";
string helloText = a.SayHello();
}
}
Let's explain the approach:
Class A is abstract, therefore it can't be instantiated.
Class AStore implements a private nested class called AInternal which just inherits A to let AStore members be able to instantiate A. Since AInternal is private, no other class than AStore can instantiate AInternal!
Class AStore can access public A members because AInternal inherits A!
You can do this with reflection too:
public class ClassA
{
// The constructor(s) have to be private
private ClassA() { }
// Whatever other code you want
}
public class ClassB
{
public static ClassA GetClassAInstance()
{
// Use reflection to get the private default constructor
ConstructorInfo constructor = typeof(ClassA).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
ClassA instance = constructor.Invoke(new object[] { }) as ClassA;
return instance;
}
}
You can find more information on the GetConstructor method here.

C# Restrict which classes can call a method

I want to be able to restrict which classes have access to call a method of another class. I have a the following:
public class A: B
{
private void DoSomething()
{
C.Method1(); // should compile
}
}
public abstract class B
{
}
public class D
{
private void DoSomething()
{
C.Method1(); // shouldn't compile
}
}
public static class C
{
public static void Method1()
{
}
public static void Method2()
{
...
Method1();
...
}
}
All of these classes are in the same assembly, but class B is in a different assembly.
My goal is for class A to be able to call C.Method1, but have class D not able to call C.Method1
I was thinking of making class C a parent class, and have class A inherit class B, but class A already inherits from class B.
Method1 doesn't belong in class A or B.
A practical use for this is when Method1 is a utility method, and should only be called by class A and class C
Without moving methods around, you'd have to make C non-static, make Method1 protected, then have B inherit from C, which would look like:
public class A : B
{
private void DoSomething()
{
C.Method1(); // should compile
}
}
public abstract class B : C
{
}
public class D
{
private void DoSomething()
{
C.Method1(); // shouldn't compile
}
}
public class C
{
protected static void Method1()
{
}
}

Categories

Resources