adding behavior to the dot operator in .NET
C#
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
DotOverload.Tests
DotOverload
.gitignore
DotOverload.sln
LICENSE.txt
README.rdoc

README.rdoc

DotOverload

What is DotOverload?

DotOverload provides a way to add aspect like behavior to both explicit dots (i.e. method calls and member access) as well as implicit dots (e.g. array indexing) in C#. An example use case is wrapping fluent method calls with an overload environment to allow for easy logging.

Hello, DotOverload!

In Objective-C, sending a message to nil results in nil, instead of an exception being thrown. It would be nice to have an easy way to have this behavior in certain contexts when using .NET. A way to define this behavior using DotOverload is

var safeDot = Dot.Bind<object,object>((current,rest) =>
{
    if(current == null)
        return null;
    else
        return rest(current);
});

Then, to use safeDot

object actuallyNull = null;
//return null instead of throwing NullReferenceException
safeDot(() => actuallyNull.ToString().ToUpper());

What is happening here underneath the hood? Basically,

actuallyNull.ToString().ToUpper()

is transformed into

(x) =>
{
  if(x == null)
    return null;
  else
  {
    return (y) =>
    {
      if (y == null)
        return null;
      else
        return (y.ToUpper())
    }(x.ToString());
  }
}(actuallyNull);

So, at the first enterance of

{
    if(current == null)
        return null;
    else
        return rest(current);
});

current will equal null, and rest is roughly

(y) =>
{
  if (y == null)
    return null;
  else
    return (y.ToUpper())
}(current.ToString());

Example: Logging

Another useful way to use DotOverload is to add logging.

var logger = Dot.Bind<T,U>((current, rest) =>
{
    someLoggerObject.Log(current);
    return rest(current);
});

This

logger(() => "hi".ToUpper().ToLower());

will output

"hi"
"HI"
"hi"

Limitations

  • Only expressions can be passed into DotOverloads, no statement lambdas are allowed.

  • Composition of DotOverloads is currently nonexistent.

  • DotOverload is currently too slow for practical use, due to the time needed to compile the expression tree. I believe that this could be sped up to acceptable speeds (i.e. in the magnitude of normal reflection) if an evaling tree walker was used instead. Patches are welcome for this!

Contributing to DotOverload

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet

  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it

  • Fork the project

  • Start a feature/bugfix branch

  • Commit and push until you are happy with your contribution

  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.

Contact

me@stuffivemade.com

Copyright

Copyright © 2011 me. See LICENSE.txt for further details.