Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I set the state of an object to the object itself in the constructor call?

Tags:

c#

constructor

I am using a pre-built third party class library (think .NET Framework...) that contains a class Foo with the following members:

public sealed class Foo {
  private object _state;
  public Foo(object state) { _state = state; }
}

Foo does not contain a public _state setter.

In a specific scenario, I want to set the state of a Foo object to the object itself.

This will NOT compile:

Foo f;
f = new Foo(f);   // Compilation error: Use of unassigned local variable 'f'

Given the above prerequisites, is there any way that I can set the state of a Foo object to the object itself?


Rationale The Timer class in Windows 8.1 does not contain the Timer(AsyncCallback) constructor which assigned the state of the Timer object with the object itself. I am trying to port .NET code that contains this Timer constructor to a Windows 8.1 class library, so my concern is How do I pass the object itself to its state member? This issue is further outlined here, but I thought it would be more efficient to also pose the principal question above.

like image 407
Anders Gustafsson Avatar asked Oct 31 '13 11:10

Anders Gustafsson


2 Answers

Workaround:

var foo = new Foo(/*params*/);
var fieldInfo = foo.GetType().GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(foo , foo);
like image 190
Dzmitry Martavoi Avatar answered Oct 16 '22 21:10

Dzmitry Martavoi


If I understand your intention correctly you want a timer whose callback references the timer itself.

Timer timer = null;
timer = new Timer(() => {
 timer.Stop(); //sample
});

Creating an object is done through the newobj instruction which atomically allocates and invokes the constructor. Without cooperation from the ctor you cannot get a reference to the unconstructed object. So there's no other way that either this approach, or reflection.

You can extract the above code into a helper method, make timer a local variable and then every timer callback will close over its own private and unchanging variable.

Timer CreateTimer(Action<Timer> callback) {
    Timer timer = null;
    timer = new Timer(() => {
     callback(timer);
    });
}
like image 27
usr Avatar answered Oct 16 '22 22:10

usr