Strange delegates and Actions behavior in .NET - c#

When I assign dog.Action as in the example:
public partial class MainWindow : Window
{
public Action<object> Action { get; set; }
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Dog dog = new Dog();
Dog dog2 = new Dog();
dog.Action = x => Action(dog2);
}
}
public class Dog
{
public int width = 5;
public Action<object> Action;
}
As you see in this example Action = null because it is not assigned.
dog.Action after assignment is Method = Void Button_Click(System.Object)
Can someone explain to me this behavior?

I can simplify your question to:
public class C
{
public void M()
{
int x = 3;
Action action = () => Console.WriteLine(x);
// 'action' now points to method called something like "<M>b__0"
}
}
If we put this code into the wonderful sharplab, we can see what the compiler generated:
public class C
{
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public int x;
internal void <M>b__0()
{
Console.WriteLine(x);
}
}
public void M()
{
<>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();
<>c__DisplayClass0_.x = 3;
Action action = <>c__DisplayClass0_.<M>b__0;
}
}
Because action captures the variable x, the compiler has had to create a whole new class called <>c__DisplayClass0_0, which has the field x on it. This class has a method called <M>b__0(), which uses the value of the field x in the call to Console.WriteLine.
In the method M(), the field <>c__DisplayClass0_0.x is used instead of the local variable x.
The delegate action points to the method <M>b__0() on this instance of <>c__DisplayClass0_0.

Related

Call base method from the base class

To remove complexity let me explain it using the below code snippet.
I want to call the parent's sum method. Now this code will call recursively and end up in stackoverflow error
public class Program
{
public static void Main()
{
var chd_obj = new child();
chd_obj.x = 10;
chd_obj.y=20;
chd_obj.sum();
}
class parent {
public int x {get;set;}
public int y {get;set;}
public virtual void sum(){
Console.WriteLine("From Base" + x+y);
}
public virtual void DoSum(){
this.sum(); // this should call the sum method in the parent class .
//But it is calling the child *sum* method
}
}
class child:parent {
public override void sum(){
base.DoSum();
}
}
}
I don't know if there is a better solution, but I would declare a private method that both sum in the base class and DoSum in the base class call:
private void SumImpl() {
Console.WriteLine("From Base" + x+y);
}
public virtual void sum(){
SumImpl();
}
public virtual void DoSum(){
SumImpl();
}
You get in infinite loop cause child class call Dosum method in Base class and again Dosum from base call child class that's why you see StackOverflow exception.
you should define what sum you mean to the compiler so the derived class can not be called again from the base class for many times.
static void Main(string[] args)
{
child sample = new child();
sample.x = 20;
sample.y = 15;
sample.sum();
Console.ReadLine();
}
public class parent
{
public int x { get; set; }
public int y { get; set; }
public virtual void sum()
{
Console.WriteLine("From Base " + (x + y));
}
public virtual void DoSum()
{
parent a = new parent();
a.x = this.x;
a.y = this.y;
a.sum();
}
}
class child : parent
{
public override void sum()
{
base.DoSum();
}
}
In this way, there is no need to create new methods but you create new instance from your parent class.
You can't do this in C#. There are workarounds, depending on your actual application.
In general, the solution requires you to extract the base's functionality into one or more non-virtual methods.
private void SumCore()
{
// Do stuff.
}
public virtual void Sum()
{
SumCore();
}

How to call a method from another class without creating an object

How can I call method whithout creating class.
Example
public class1 {
class2 = new class2();
int size;
private void method() {
size = class2.size;
}
}
public class2 {
private void method() {
//call method from class1
}
}
You can do that making the method of class1 static (add the static reserved word before private)
That way you can call the method as class1.method();
Hope this is what you are looking for!
I mean it:
public Class1 {
Class2 class2 = new Class2();
public int size;
public Class1() {
class2.handler += method1;
}
private void method1() {
size = class2.size;
}
}
public Class2 {
...
public int size;
public delegate void Handler();
public Handler handler;
private void method2() {
size = UpdateSize();
handler?.Invoke();
}
private int UpdateSize() {
...
}
}

Cast MyClass<T> to MyClass<dynamic>

The follow code does not compile:
public class Test
{
public void Run()
{
List<MyClass<dynamic>> listOfMyClasses = new List<MyClass<dynamic>>();
MyClass<dynamic> myClass = new MyClass<int>(); // Error here
listOfMyClasses.Add(myClass);
}
public class MyClass<T>
{
public void DoSomething() { }
public void DoSomethingSpecial<T>(T t) { }
}
}
However, I believe it makes sense logically (please let me know if I'm mistaken). Presumably it is useful, for I can call DoSomething without knowing the type parameter. How can I accomplish the addition of myClass to the list?
Instead of using a list of MyClass<dynamic> just use a List of dynamic:
public void Run()
{
List<dynamic> listOfMyClasses = new List<dynamic>();
dynamic myClass = new MyClass<int>();
listOfMyClasses.Add(myClass);
}
public class MyClass<T>
{
public void DoSomething() { }
}

C# How to access method of a class from another class it instantiates?

I have 2 classes where 1 class is like the main class and I have a secondary class which is instantiated from the main class. How am I able to use the main class' method from the secondary class. Here's code to give an illustration of what I want.
public class MainClass
{
private SecondaryClass secondaryClass;
private int testValue;
public MainClass()
{
this.secondaryClass = new SecondaryClass();
testValue = 0;
}
public void updateTestValue (int val)
{
testValue = val;
}
}
public Class SecondaryClass : Form
{
public SecondaryClass()
{
}
private void button1_click(Object sender, EventArgs e)
{
// I want to be able to do this:
primaryClass.updateTestValue(100);
}
}
You can make classes communicate without having one derive from another.
public class MainClass
{
private SecondaryClass secondaryClass;
private int testValue;
public MainClass()
{
this.secondaryClass = new SecondaryClass(this.UpdateTestValue);
testValue = 0;
}
public void UpdateTestValue (int val)
{
testValue = val;
}
}
public class SecondaryClass : Form
{
private Action<int> UpdateValue { get; }
public SecondaryClass(Action<int> updateValue)
{
this.UpdateValue = updateValue;
}
private void button1_click(Object sender, EventArgs e)
{
this.UpdateTestValue(100);
}
}
In this organization, primary class is passing a delegate to its own instance-level method when it creates the secondary class. Secondary class calls that delegate when appropriate, without ever knowing what function that is.
This is the example of the callback pattern.
There are other variants of the same idea. For example, primary class could implement an interface which defines the UpdateValue method. Then, it passes this reference to every object which needs access to that method. Other objects, like an object of secondary class, would then simply call a method of that interface, once again not knowing that it is in fact the primary class they are referencing.
public interface IListener
{
void Update(int value);
}
public class MainClass : IListener
{
private SecondaryClass secondaryClass;
private int testValue;
public MainClass()
{
this.secondaryClass = new SecondaryClass(this);
testValue = 0;
}
public void Update(int val)
{
testValue = val;
}
}
public class SecondaryClass : Form
{
private IListener Listener { get; }
public SecondaryClass(IListener listener)
{
this.Listener = listener;
}
private void button1_click(Object sender, EventArgs e)
{
this.Listener.Update(100);
}
}
The price of this solution is one additional type in the system (interface IListener), and the benefit is that you can avoid working with delegate syntax. Delegates have a drawback that their arguments have no names, and therefore you can easily make a bug if you mix them up.
public class MainClass: Form
{
private int testValue;
public MainClass()
{
testValue = 0;
}
public void updateTestValue (int val)
{
testValue = val;
}
}
public class SecondaryClass : MainClass
{
public SecondaryClass()
{
}
private void button1_click(Object sender, EventArgs e)
{
// I want to be able to do this:
updateTestValue(100);
}
}
A class can only have one base class
What you could do is move the :Form base class up to the primary class and then from your secondary class have it's base class as Primary class and use the functions as follows.
public class PrimaryClass : Form
{
private int testValue;
public void PrimaryClassMethod()
{
Console.WriteLine("Method from Primary Class");
}
public void UpdateTestValue (int val)
{
testValue = val;
}
}
public class SecondaryClass : PrimaryClass
{
public void CallPrimaryClassMethod()
{
this.PrimaryClassMethod();
this.UpdateTestValue(10000);
}
}
https://dotnetfiddle.net/PC2WVu

How to Avoid Assignment of Private Members in Constructor

I often find myself doing this:
class MyClass
{
public MyClass(int x)
{
this.x = x;
}
private int x;
...
}
Every time I add a new private member variable for configuration, I need to add it to the constructor's parameter list, to the constructor body, and to the class as a member. Is there a good programming pattern for avoiding the extra typing?
Generally speaking, If you instantiate a class with a bunch of private members that you have to pass into the constructor, you're doing something problematic already.
MyClass myClass = new MyClass(x, y, z, 7, 'c', someOtherClass)
If appropriate, you can encapsulate related fields into a struct or a different class like so
class MyClass
{
public MyClass(Coordinates coords)
{
this.coords = coords;
}
private Coordinates coords;
}
public struct Coordinates
{
public int X{get; set;}
public int Y{get; set;}
public int z{get; set;}
}
and then you can instanciate it with
MyClass myClass = new MyClass(new Coordinates() { X = 1, Y = 2, Z = 3 });
Without a particular implementation, It's kinda hard to determine the optimal solution, but if you don't actually have to set the fields from outside your class, you can do something like
class MyClass
{
public MyClass()
{
}
private int x = 2;
...
}
or
class MyClass
{
public MyClass()
{
this.x = 2;
}
private int x;
...
}
I find that I can abuse inheritance to accomplish my goal. I set up a "Loader" subclass that has the sole purpose in life of plugging in the dependencies of the base class. Then we can work with the base class and forget about the loader.
Then again, this has the horrible side-effect of preventing use of these protected member variables in the base constructor -- we need to use a .Start() function or something like that instead. So, this is a pretty bad solution, although saving some keystrokes.
public class MyClass
{
protected int param1;
protected int param2;
public void DoStuff()
{
Console.WriteLine(param1 + param2);
}
}
public class MyClassLoader : MyClass
{
public MyClassLoader()
{
param1 = 1;
param2 = 2;
}
}
class Program
{
static void Main(string[] args)
{
MyClass myObj = new MyClassLoader();
myObj.DoStuff();
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}

Categories

Resources