Skip to content

Instantly share code, notes, and snippets.

@danhab99
Last active June 22, 2017 11:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danhab99/1bfebab758565df72297d99108addc7a to your computer and use it in GitHub Desktop.
Save danhab99/1bfebab758565df72297d99108addc7a to your computer and use it in GitHub Desktop.
This object and it's interface can be used to catch the accessors in an object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ObjDB
{
public interface IEventedType<T>
{
T Value { get; set; }
event EventHandler<T> OnSet;
event EventHandler<T> OnGet;
}
public class EventedType<T> : IEventedType<T>
{
private T _value;
public T Value {
get
{
var temp = value;
OnGet?.Invoke(this, temp);
return temp;
}
set
{
var temp = value;
_value = temp;
OnSet?.Invoke(this, temp);
}
}
public EventedType()
{
}
public EventedType(T obj)
{
Value = obj;
}
public static implicit operator T(EventedType<T> o) => o.Value;
public static explicit operator EventedType<T>(T o) => new EventedType<T>(o);
public event EventHandler<T> OnSet;
public event EventHandler<T> OnGet;
}
}
@cyanite
Copy link

cyanite commented Jun 20, 2017

You get null reference exceptions whenever you access Value since the events aren't initialized. You need to call them with WasGot?.Invoke(this, _value) or similar.

@danhab99
Copy link
Author

Like the edits I just made?

@BanalityOfSeeking
Copy link

    public T Value {

        get

        {

            var temp = _value;

            OnGet?.Invoke(this, temp);

            return temp;

        }

        set

        {

            var temp = _value;

            _value = temp;

            OnSet?.Invoke(this, temp);

        }

    }

@casparkleijne
Copy link

Can you explain to me why you choose for this approach and not a INotifyPropertyChanged implementation?

@vasyop
Copy link

vasyop commented Jun 21, 2017

@casparkleijne

It's a wrapper around the process of 'listening' to a variable set/get.
You can go like:
private EventedType Name;
and in the constructor:
Name.OnSet+=(s,e)=>HandleNameChange();
The alternative is to create a property and an event and raise it and check for null etc. Everytime. Everywhere. Forever. Not being DRY. Not cool, man.

@kirides
Copy link

kirides commented Jun 22, 2017

So its like... a regular Property, which is not INotifyPropertyChanged compatible?
isn't a snippet like ...

private int _val;
public int Val { get => GetProperty(ref _val); set => SetProperty(ref _val, value); }

// SetProperty
public void SetProperty<T>(ref T field, T value, Action<T> onSet = null, [CallerMemberName] propName = null)
{
  if(Equals(field, value)) return;
  field = value;
  RaisePropertyChanged?.Invoke(propName);
  onSet?.Invoke(value);
}
// GetProperty
public T GetProperty<T>(ref T field, Action<T> onGet = null)
{
  var val = field;
  onGet?.Invoke(val);
  return val; 
}

... better?
Please feel free to tell me about the benefits. I might be too stupid to see them right away

The only benefit i see, is that you can have multiple subscribers...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment