I need to be able to monitor a large number of objects for changes. In nearly any case, I could just use INotifyPropertyChanged
and call it a day. However, my situation isn't as simple. The goal of my project is to create a simulation where any object can be plugged in, monitored, and accessed.
The plugging in is done via reflection using a Fluent API that designates properties and fields to include in the simulation's environment. It looks something like this:
public void DeclareVariables( IVariableBuilder builder )
{
builder.Include( x => x.PropertyA );
builder.Include( x => x.FieldA );
}
The properties and fields are then wrapped in a Variable
class and stored in an Environment
class.
public class Variable<T> : IVariable
{
private FieldInfo _field; // Properties are turned into FieldInfo via k__BackingField
private object _obj;
public string Id
{
get => $"{_obj.GetType}-{_field.Name}";
}
public T Value
{
get => _field.GetValue( _obj );
}
}
public class Environment
{
private Dictionary<string, IVariable> _variables;
}
This properly stores references to all of the fields and properties I am trying to include. However, I want to be able to monitor all of these for changes, and most of the included fields are either closed-source classes or primitives, both of which do not implement INotifyPropertyChanged` or cannot be derived.
I come from a JavaScript background, where you can accomplish this by creating an object proxy that can override property getters and setters, and since JavaScript is duck-typed, you can just replace the actual object instance in-place with the proxy.
Is there a way to do the same in C#? I'd imagine C#'s type safety rules would not allow a practice like this, especially with primitives. As far as I am aware, however, the only way to monitor these classes would be to somehow intercept operations where the value is being set.