c# - dynamic keyword enables "maybe" monad? -
so have in c# lib:
public static tout ifnotnull<tin, tout> (this tin instance, func<tin, tout> func) { return instance == null ? default(tout) : func(instance); } used like:
datetime? expiration = promo.ifnotnull(p => p.termsandconditions.expiration) .ifnotnull(e => e.date); i keep wracking brain trying figure out how use c# 4 dynamic keyword enable syntax instead:
datetime? expiration = promooffer.termsandconditions.maybe() .expiration.maybe() .date; i had couple examples thought worked broke down when start chaining maybe()s.
any ideas?
(am wasting time? maybe() win on ifnotnull())?
i don't think using dynamic type idea here, because syntax isn't going better , sacrifice type safety (and intellisense) using dynamic typing.
however, here example of can do. idea wrap objects dynamicwrapper (your monadic value :-)) can either contain null value or actual value. inherit dynamicobject , delegate calls actual object (if there any) or return null (that monadic bind):
class dynamicwrapper : dynamicobject { public object object { get; private set; } public dynamicwrapper(object o) { object = o; } public override bool trygetmember(getmemberbinder binder, out object result) { // special case used @ end actual value if (binder.name == "value") result = object; // binding on 'null' value - return 'null' else if (object == null) result = new dynamicwrapper(null); else { // binding on value - delegate underlying object var getmeth = object.gettype().getproperty(binder.name).getgetmethod(); result = new dynamicwrapper(getmeth.invoke(object, new object[0])); return true; } public static dynamic wrap(object o) { return new dynamicwrapper(o); } } the example supports properties , uses reflection in pretty inefficient way (i think optimized using dlr). here example how works:
class product { public product { get; set; } public string name { get; set; } } var p1 = new product { = null }; var p2 = new product { = new product { name = "foo" } }; var p3 = (product)null; // prints '' p1 , p3 (null value) , 'foo' p2 (actual value) string name = dynamicwrapper.wrap(p1).another.name.value; console.writeline(name); note can chain calls freely - there special @ beginning (wrap) , @ end (value), in middle, can write .another.another.another... many times want.
Comments
Post a Comment