Jan 22, 2010

Nullable notes

Nullable is value type object. But the following code can be compiled.

int? x = null

Isn't "null" supposed to be used with reference type, why it can be assigned with value type? It turns out to be just syntax suger, and the compiler emit the following code. It does not call any constructor.


IL_0001:  ldloca.s   x
IL_0003:  initobj    valuetype [mscorlib]System.Nullable`1<int32>

However, if you write the following code, compiler will emit the msil like the following. It call the constructor.


int? y = 123;

IL_0009:  ldloca.s   y
IL_000b:  ldc.i4.s   123
IL_000d:  call       instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)

//called
public Nullable(T value) {
    this.value = value; 
    this.hasValue = true;
} 

Nullable has two implicit converter that help you to write the following code.


int? y = 246; //implict conversion that create a Nullable on the fly, using the following implicit operator
public static implicit operator Nullable<T>(T value) { 
    return new Nullable<T>(value);
}

int z = (int)y; //explict conversion using the following explicit operator, this is not cast operation, this may throw exception, if Nullable.HasValue is false
public static explicit operator T(Nullable<T> value) { 
    return value.Value;
} 

public T Value {
    get { 
        if (!HasValue) { 
            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
        } 
        return value;
    }
}


You may wonder why we don't can write the following code?


int z = y; //error, you can not do this, because there is not implicit conversion

This is because we don't have implict converter to convert a Nullable<T> to T. If we have had the following operator, we will be able to write the code above.


public static implicit operator T(Nullable<T> value) { 
   if (!HasValue) 
   { 
       return value.Value; 
   }
   else
   {
       return default(T);
   }
} 

But Why we have explicit converter but not implicit converter. If we have had this operator, there will be no difference in using Nullable<T> and T. The purpose of Nullable<T> is to use value type T like a reference type. That is why in the Value property will throw exception if there is not value, we want to using a value type like a reference type!!! See the following example.

int? x = null;
    if (x == null)//msil will be like if (x.HasValue)
    {
       Console.WriteLine("x is null");
    }

Although we can not implicitly convert Nullable<T> to T, but C# compiler and CLR, allow us use Nullable<T> like T in most of case. So the following code is legal.


int? y = 0;
y++;

//compiler will emit the following code
//if (y.HasValue)
//{
//    int temp = y.Value;
//    temp++;
//    y = temp;
//}

Int32? x = 5;
Console.WriteLine (x.GetType()); // it is "System.Int32"; not "System.Nullable<int32>"

Int32? n = 5;
Int32 result = ((IComparable) n).CompareTo(5); // Compiles & runs OK
Console.WriteLine(result); // 0

/*
If the CLR didn't provide this special support, it would be more cumbersome for you to write code to call an interface method on a nullable value type. You'd have to cast the unboxed value type first before casting to the interface to make the call: */

Int32 result = ((IComparable) (Int32) n).CompareTo(5); // Cumbersome

Null-Coalescing ?? operator works with reference type.


string s = null
//
string s2 = s ?? "something";
// this line is be compiled to 
  IL_0003:  ldloc.0
  IL_0004:  dup
  IL_0005:  brtrue.s   IL_000d
  IL_0007:  pop
  IL_0008:  ldstr      "something"
  IL_000d:  stloc.1

But c# compiler, make "??" works for Nullable as well. But underneath the emitted code is completely different, like the following


int z = y ?? 100;

//it is equivalent as 
//z = (y.HasValue) ? y.Value : 100

//it is also equivalent as 
//z = y.GetValueOrDefault(100);

To sum this up, the purpose of Nullable type is to let a value type has a null value, but compiler also let us use it as value type as well.

make your obsolete method invisible

When I started to use moq, there was lots example of moq that use mock.Setup method, althought these code can be compile. The this method is not shown up in intellisense popup, it turns out in the latest version of moq, it hide this memeber like below.


[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Expect has been renamed to Setup.", false)]
public ISetup<T> Expect(Expression<Action<T>> expression);

Jan 21, 2010

When a constructor is not called

Normally, when we build a .net object, clr will call the constructor.
But In a few situations, an instance of a type can be created without an instance constructor being called. In particular, calling Object's MemberwiseClone method allocates memory, initializes the object's overhead fields, and then copies the source object's bytes to the new object. Also, a constructor is usually not called when deserializing an object.

Jan 19, 2010

Links in asp.net

There are serveral helper class which help to generate links.

//When you generate link with the same controller 
Html.ActionLink();

//When you generate link with the different controller
Html.RouteLink();


Ajax.ActionLink(); //ajax version of Html.ActionLink(..)
Ajax.RouteLink();  //ajax version of Html.RouteLink(..)

//generate url only, not anchor tag
Url.RouteUrl();


//eventually all method will call
internal static string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
    RouteValueDictionary mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, routeValues, includeImplicitMvcValues);

    VirtualPathData vpd = routeCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues);
    if (vpd == null) {
        return null;
    }

    string modifiedUrl = PathHelpers.GenerateClientUrl(requestContext.HttpContext, vpd.VirtualPath);
    return modifiedUrl;
}

ajax header

Most of the javascript library add a header, when it use ajax to make a http quest.

x-requested-with: XMLHttpRequest

Expression, Expression Tree, Lamda, Lamda expression, IQueryable

Expression trees in .net 3.5 provide an abstract way of representing code as a tree of objects, these objects are expressions. As it said, Expression tree is a tree of expressions, and expression tree is also an expression, a composite of expressions. In .net there is no such type ExpressionTree, they are all Expressions.

Expression firstArgExpression = Expression.Constant(2);
Expression secondArgExpression = Expression.Constant(3);
Expression addExpressionTree = Expression.Add(firstArgExpression, secondArgExpression);

Expression, and expression tree is not much fun, until it can do something. So to do something, and we need to compile it into code, and execute the code. This a multiple steps process. First we need to convert the expression tree into a DelegateReadyExpression, then we compile DelegateReadyExpression into delegate instance, which is essentially a method, and finally we execute the method. In .net there is no such class DelegateReadyExpression, it is actually named LambdaExpression. LambdaExpression is an abstract sub-class of Exppression, it has a method "public Delegate Compile();". You may ask, why named LambdaExpression, why not DelegateReadyExpression, I will cover later in this post. The following code does these steps.

LambdaExpression lamdaExpression = Expression.Lambda(addExpressionTree);
Delegate unTypedDelegate = lamdaExpression.Compile();
object untypedResult = unTypedDelegate.DynamicInvoke();
Console.WriteLine(untypedResult);

Seemingly, the above code is not good enough. As LambdaExpression is not strongly typed. We need to create a strongly type LamdaExpression, which is Expression<T>.


Expression<Func<int>> stronglyTypedLamdaExpression = Expression.Lambda<Func<int>>(addExpressionTree);
Func<int> stronglyTypedDelegate = stronglyTypedLamdaExpression.Compile();
int result = stronglyTypedDelegate();
Console.WriteLine(result);

So the purpose of expression, and expression tree is light weight code generation. But it still too complicated to use. If we want to generate the following method,

bool IsStartedWith(string x, string y)
{
  return x.StartsWith(y);
}

We need programatically to do the following.

MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var target = Expression.Parameter(typeof(string), "x");
var methodArg = Expression.Parameter(typeof(string), "y");
Expression[] methodArgs = new[] { methodArg };
Expression call = Expression.Call(target, method, methodArgs);
var lambdaParameters = new[] { target, methodArg };
var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambdaParameters);
var compiled = lambda.Compile();
Console.WriteLine(compiled("First", "Second"));
Console.WriteLine(compiled("First", "Fir"));

Seemingly this is too tedious. It turns out Lamda Expression is very good to represent the an expression tree. Here we just use lamda to represent lamda expression. There are two forms of lambda expression (type Expression), statement lamda, expression lamda. The body of statement lambda expression can contains statements, and expression lambda expression can only contains expression only. We already know that we can use lambda expression represent a anonymous method, delegate, like the following. Both statement lamda and expression can do that.

Func<string, string, bool> IsStartedWith = (x, y) =>
{
    return x.StartsWith(y);
};
//or
Func<string, string, bool> IsStartedWith = (x, y) => x.StartsWith(y);

Console.WriteLine(IsStartedWith("First", "Fir"));

But statement lamda is not good to represent an tree of object, but expression lamda is good to represent a tree because is a tree in syntax. So expression lamda can be converted in a expression tree.

Expression<Func<string, string, bool>> stronglyTypedLamdaExpression = (x, y) => x.StartsWith(y);
Assert.IsTrue(stronglyTypedLamdaExpression is LambdaExpression);

var isStartedWith = stronglyTypedLamdaExpression.Compile();
var result = isStartedWith("First", "Fir");
Assert.IsTrue(result);

So you may understand why DelegateReadyExpression is named as LamdaExpression, because DelegateReadyExpression can be easily expressed as "lambda expression", so lets just call it LamdaExpression. We use "lambda expression" to create expression tree (Expression) then we convert expression tree into DelegateReadyExpression(LamdaExpression) object. LamdaExpression is ready to to complied into delegate. The following error may help you understand this process.

//A lambda expression with a statement body cannot be converted to an expression tree
Expression<Func<int>> y = () => { return 5; };

If you decompile the above code with reflector, it will be the following. But using expression lamda is much elegant want to represent code.

Expression<Func<string, string, bool>> stronglyTypedLamdaExpression = (x, y) => x.StartsWith(y);
//complied to 
ParameterExpression x;
ParameterExpression y;
Expression<Func<string, string, bool>> stronglyTypedLamdaExpression = 
    Expression.Lambda<Func<string, string, bool>>
    (
        Expression.Call(
                          x = Expression.Parameter(typeof(string), "x"), 
                          (MethodInfo)methodof(string.StartsWith), 
                          new Expression[] { y = Expression.Parameter(typeof(string), "y") }
                       ), 
        new ParameterExpression[] { x, y }
    );

In summary, "Both expression lambda expression and statement lambda expression" can be pre-compiled to delegate in compiled time by compiler. "only expression lambda expression" can be used to create expression tree(Expression), "statement lambda expression" can not be compiled to expression tree(Expression object). Expression object can be convert to "LamdaExpression object" or "Expression<T>", then compiled to delegate in runtime. Expression object can be also compiled other forms of code using IQuerable model.

Jan 15, 2010

Namespace and Controller in asp.net mvc

In .net a type has a namespace, if two type names are the same, but they live in different namespace, this is not a problem. So when asp.net resolve the type with the controller name, DefaultController factory by default does not care namespace. So if there are two Controllers with the sname name in your reference dlls, then there will be an exception saying ambigous controllers found. But you can help the DefaultControllerFactory to resolve this conflict using the follow sample code.

string[] routeContollerSearchHints_NameSpace = new string[] { "MvcAppTest.Controllers" };
string routeName = "Default";
string url = "{controller}/{action}/{id}";
object defaults = new { controller = "Home", action = "Index", id = "" };
object constrants = null;
routes.MapRoute(routeName, url, defaults, constrants, routeContollerSearchHints_NameSpace);

// or 
string[] globalContollerSearchHints_NameSpace = new string[] { "MvcAppTest.Controllers" };
ControllerBuilder.Current.DefaultNamespaces.UnionWith(globalContollerSearchHints_NameSpace);

Test Example in System.Web.Mvc

Because the mvc project and test project are seperate, we need the test project to see the internal member in System.Web.Mvc project, so there is a attribute in the mvc project.

[assembly: InternalsVisibleTo("System.Web.Mvc.Test")]

The effort to make the project testable of the mvc project is very obvious. For example, to make DefaultControllerFactory testable, the class has a property setter, so that test project can inject mocking object.

DefaultControllerFactory factory = new DefaultControllerFactory();
MockBuildManager buildManagerMock = new MockBuildManager(new Assembly[] { });
ControllerTypeCache controllerTypeCache = new ControllerTypeCache();

factory.BuildManager = buildManagerMock;
factory.ControllerTypeCache = controllerTypeCache;

// Act
Type controllerType = factory.GetControllerType("sometype");

// Assert
Assert.IsNull(controllerType, "Shouldn't have found a controller type.");
Assert.AreEqual<int>(0, controllerTypeCache.Count, "Cache should be empty.");

//member of DefaultControllerFactory
internal IBuildManager BuildManager {
    get {
        if (_buildManager == null) {
            _buildManager = new BuildManagerWrapper();
        }
        return _buildManager;
    }
    set {
        _buildManager = value;
    }
}

internal ControllerBuilder ControllerBuilder {
    get {
        return _controllerBuilder ?? ControllerBuilder.Current;
    }
    set {
        _controllerBuilder = value;
    }
}

Another example is as follow. Even we need to increase performance of the by using staticControllerTypeCase, we still allow test project to inject an _instanceControllerTypeCase for testing.

//member of DefaultControllerFactory
internal ControllerTypeCache ControllerTypeCache {
    get {
        return _instanceControllerTypeCache ?? _staticControllerTypeCache;
    }
    set {
        _instanceControllerTypeCache = value;
    }
}

//member of ControllerContext
//RouteData can be mocked.
public virtual RouteData RouteData {
    get {
        if (_routeData == null) {
            _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();
        }
        return _routeData;
    }
    set {
        _routeData = value;
    }
}

Jan 12, 2010

Custom T4 host for asp.net mvc

T4 template can be hosted by different environment. By default template is not HostSpecific. When you want to reuse a template to generate different file, you can customize the generation process by providing a dialog window. This is what MvcTextTemplateHost does. ASP.NET MVC tools is included in C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Microsoft.VisualStudio.Web.Extensions.dll , which is not a open source project. But you can use Reflector to view some of its implementation. The dll provide some context menu to add view , add controller , and some dialog box for use to customize the code generation. Here is article about the MvcTextTemplateHost

Jan 6, 2010

Using lambda expression to remove string expression

public class Customer
{
    public string Name { get; set; }
}

[TestMethod]
public void can_get_value_from_lamda_expression()
{
    Customer c = new Customer() { Name = "fred" };
    //
    Expression<Func<Customer, object>> propertyExpression = cust => cust.Name;
    Assert.AreEqual("Name", GetPropertyName(propertyExpression));
    Assert.AreEqual("fred", GetPropertyValue(c, propertyExpression));
    //
    Assert.AreEqual("Name", GetPropertyName<Customer>(cust => cust.Name));
    Assert.AreEqual("fred", GetPropertyValue(c, cust => cust.Name));
}

private string GetPropertyName<T>(Expression<Func<T, object>> propertyExpression)
{
    return (propertyExpression.Body as MemberExpression).Member.Name;
}

private object GetPropertyValue<T>(T target, Expression<Func<T, object>> propertyExpression)
{
    Func<T, object> getValue = propertyExpression.Compile();
    return getValue(target);
}