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

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -