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