# Sunday, March 02, 2008

A little sooner than expected, I decided to publish the source code for LazyParser.NET on CodePlex.

LazyParser.NET is a lightweight C# expression parser that allows you to add late-bound expression parsing to your .NET applications. It will allow you to use (user supplied?) C# expressions to be used in a variety of situations:

  • Validation expressions
  • Blog engines
  • Content management systems
  • Calculators
  • ...

The following features are supported in this release:

  • Full C# 2.0 expression syntax (exceptions listed below)
    • All numeric and boolean operators
    • Method calls (isolated and member/static methods)
    • Constructor calls
    • typeof() expression
    • All literals (numeric, character, string), including character and string escaping
  • C# 2.0 compliant (operator precedence, implicit conversions, nullable type lifting, type promotion, etc...)
  • Late binding
  • Field access interceptors at runtime
  • Support for member fields, properties and methods
  • Support for static fields, properties and methods
  • Function injection using delegates

Not supported in this release:

  • Indexing operator ( "[]" )
  • Conditional operator ( a ? b : c)
  • Unary operators (except "!", which is supported)
  • "is" and "as" operators

An example of how you can use this library:

ParserContext context = new ParserContext();
 
context.Add("Math", new ClassName(typeof(Math)));
context.Add("SomeString", "Hi there!");
context.Add("SomeNumber", 20);
context.Add("fmt",  new StaticMethod(typeof(String), "Format"));
 
CSharpParser parser = new CSharpParser();
 
string stringValue = parser.Evaluate<string>("fmt(\"I said: {0}\", SomeString)", context);  
// returns "I said: Hi there!" int intValue = parser.Evaluate<int>("Math.Max(10, SomeNumber)" , context);
// returns 20 double doubleValue = parser.Evaluate<double>("SomeNumber * 2.0", context);
// returns 40.0

 

This is just the first pre-1.0 release of this library, so there may be some small problems. Any suggestions for improvement or bug reports are more than welcome. Please use the CodePlex discussion area and the issue tracker for this purpose

UPDATE: LazyParser.NET v0.9.1 has been published on CodePlex, with support for indexing operators.

kick it on DotNetKicks.com
Sunday, March 02, 2008 11:33:19 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [6] -

Working with nullable types using reflection is not that hard, but sometimes you have to think about it for a bit or browse the help file before you can actually use it correctly.

What I will list here is not rocket science, but it could be helpful to have all the nullable-related stuff in one short article.

Get the acutal (non-nullable) type of nullable (if it's not nullable, the type itself is returned):

Type realType = Nullable.GetUnderlyingType(type) ?? type;

Determine if a type is a nullable type:

bool isNullable = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);

Create a generic type based on a non-nullable type:

Type nullableType = typeof(Nullable<>).MakeGenericType(type);

Finally, get the type of the elements of an array type:

Type elementType = arrayType.GetElementType();

 

As I said before, everyone could find the answers in the .NET documentation relatively quickly, but this quick reference could come in handy. If not, just ignore me :-)

kick it on DotNetKicks.com
Sunday, March 02, 2008 11:05:38 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -

# Saturday, March 01, 2008

In two of my open source projects (CoolStorage.NET and ProMesh.NET), I have to parse expressions from a string at runtime. Both products include a simple parser that supports most of the .NET expression syntax, but it is still too restricted compared to real C# expressions.

So I decided to create a separate C# open source project that allows you to include C# 2.0 expression parsing in your application.

The features of this library:

  • Light-weight (less than 60KB) with no dependencies
  • Late-bound context
  • Full C# 2.0 syntax
  • All .NET 2.0 types supported, including nullables
  • Support for calling any .NET method and creating any .NET object (provided you allow it)

The late-bound aspect is quite important. The expression parser can be called with a context object that contains all the variables and classes you want to expose to the expression. It is obvious that the expression parser doesn't know about the types of the objects you supplied, so when evaluating the expression, LazyParser.NET will use the same logic as the C# 2.0 compiler to determine what overloaded method to call, or what type of value to return from an expression, based on the runtime types in the context.

The project is almost ready to published as version 0.9. I still need to add some stuff like indexing operators, type casting and conditional operators, but other than that is working great.

The first version will be published on CodePlex sometime next week.

UPDATE: LazyParser.NET 0.9.1 has been published on CodePlex

kick it on DotNetKicks.com
Saturday, March 01, 2008 9:56:26 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [3] -

# Wednesday, November 14, 2007

Everyone knows that an easy way to represent binary data in a normal ASCII, is to use Base64. Most people also know about the Convert.ToBase64String() and Convert.FromBase64String() methods in the .NET Framework. But how do you use this knowledge to convert any (serializable) object to/from a string, in as few lines of code as posssible?

Well, most (if not all) solutions I found on the net are making things a lot more complicated than they should be. So I decided to write my own and share it with you:

The 20-line Base64 Serializer/Deserializer

public static class Base64Serializer
{
    public static string Serialize(object obj)
    {
        using (MemoryStream memStream = new MemoryStream())
        {
            new BinaryFormatter().Serialize(memStream, obj);

            return Convert.ToBase64String(memStream.ToArray());
        }
    }

    public static T Deserialize<T>(string s)
    {
        using (MemoryStream memStream = new MemoryStream(Convert.FromBase64String(s)))
        {
            return (T) new BinaryFormatter().Deserialize(memStream);
        }
    }
}

kick it on DotNetKicks.com
Wednesday, November 14, 2007 4:59:25 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -

# Tuesday, October 23, 2007

When a software tester comes up to your desk and complains about a bug, and you have no idea what to tell him, just use the following list and pick a number:

  1. This has always worked fine...
  2. I didn't change anything...
  3. It works here!
  4. Weird, I tested this!
  5. My unit tests were all green!
  6. Are you using the latest build?
  7. ... probably changed the code.
  8. I've never seen this error before...
  9. That's not my code!
  10. I think this has never worked before...
  11. The database changes probably haven't been done yet.
  12. Was that included in the functional design?

As Dave Barry would say: I swear I'm not making this up! The "excuses" in this list are taken from what I hear every day. Sometimes they even make sense :)

kick it on DotNetKicks.com
Tuesday, October 23, 2007 10:01:58 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -