javascript - Is there a knockoutjs computed equivalent in C#? -
i use knockout.js lot , love concept of computed observable.
idea computed observable defined function of other observable , takes dependence on observable variable used inside of it.
allow interesting scenarios dependent variables update once single observable change impact other computed variables.
http://knockoutjs.com/documentation/computedobservables.html
question :does c# have equivalent using either standard libraries or open source library?
answer : yes, there is.
interface inotifypropertychanged
doing that, in system.componentmodel
namespace.
interface contains propertychanged
event, trigger when property changed.
c# 4 , below example
public class datacs4 : inotifypropertychanged { #region inotifypropertychanged members public event propertychangedeventhandler propertychanged; protected virtual void onpropertychanged(string propertyname) { propertychangedeventhandler handler = propertychanged; if (handler != null) handler(this, new propertychangedeventargs(propertyname)); } #endregion // represent observable private int firstnumber; public int firstnumber { { return firstnumber; } set { if (value == firstnumber) return; this.firstnumber = value; onpropertychanged("firstnumber"); onpropertychanged("sum"); } } // represent observable private int secondnumber; public int secondnumber { { return secondnumber; } set { if (value == secondnumber) return; this.secondnumber = value; onpropertychanged("secondnumber"); onpropertychanged("sum"); } } // represent computed public int sum { { return firstnumber + secondnumber; } } }
this simple example sum 2 integers
have firstnumber
property, (which consider knockout observable)
have secondnumber
property (which consider knockout observable)
, have sum
property (which consider knockout computed).
now every time change either firstnumber
or secondnumber
(by calling corresponding set functions), notifying subscribers properties (this done calling onpropertychanged
method)
also calling onpropertychanged
sum
property notify subscribers property value of property has changed.
note common pattern when using wpf + mvvm pattern.
when using c# 5.0 or c# 6.0, benefits new features make code little easier
c# 5.0 example
public class datacs5 : inotifypropertychanged { #region inotifypropertychanged members public event propertychangedeventhandler propertychanged; protected virtual void onpropertychanged([callermembername]string propertyname = null) { propertychangedeventhandler handler = propertychanged; if (handler != null) handler(this, new propertychangedeventargs(propertyname)); } #endregion // represent observable private int firstnumber; public int firstnumber { { return firstnumber; } set { if (value == firstnumber) return; this.firstnumber = value; onpropertychanged(); onpropertychanged("sum"); } } // represent observable private int secondnumber; public int secondnumber { { return secondnumber; } set { if (value == secondnumber) return; this.secondnumber = value; onpropertychanged(); onpropertychanged("sum"); } } // represent computed public int sum { { return firstnumber + secondnumber; } } }
there 2 changes here
protected virtual void onpropertychanged([callermembername]string propertyname = null)
, putting attribute before parameter of method, compiler know name of property called method automatiilcay, without passing property name manually, can write following statement.onpropertychanged();
represent second modification.
note: callermembername
attribute exists in system.runtime.compilerservices
namespace
c# 6.0 example
with c# 6.0 simplify implemenation of onpropertychanged
method.
public class datacs6 : inotifypropertychanged { #region inotifypropertychanged members public event propertychangedeventhandler propertychanged; // c# 6.0 protected void onpropertychanged([callermembername] string propertyname = null) { propertychanged?.invoke(this, new propertychangedeventargs(propertyname)); } #endregion // represent observable private int firstnumber; public int firstnumber { { return firstnumber; } set { if (value == firstnumber) return; this.firstnumber = value; onpropertychanged(); onpropertychanged("sum"); } } // represent observable private int secondnumber; public int secondnumber { { return secondnumber; } set { if (value == secondnumber) return; this.secondnumber = value; onpropertychanged(); onpropertychanged("sum"); } } // represent computed public int sum => firstnumber + secondnumber; }
update
responding following comment :
interesting! here have manage dependencies yourself. have trigger property changed sum. in knockout figures out properties shall trigger property changed on computed. way of doing that?
i think have 2 options (at least)
propertychanged library on github.
description of library :injects inotifypropertychanged code properties @ compile time
here new code after download library nuget
[propertychanged.implementpropertychanged] public class data { public int firstnumber { get; set; } public int secondnumber { get; set; } public int sum => secondnumber + firstnumber; }
cheers !.
Comments
Post a Comment