Skip to content

Instantly share code, notes, and snippets.

@danhab99
Last active June 22, 2017 11:54
Show Gist options
  • Select an option

  • Save danhab99/1bfebab758565df72297d99108addc7a to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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
Copy Markdown
Author

Like the edits I just made?

@BanalityOfSeeking
Copy link
Copy Markdown

    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
Copy Markdown

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

@vasyop
Copy link
Copy Markdown

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
Copy Markdown

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