Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

May 19, 2010

Functional aspect of c#

Two generic delegate in c#, makes c# look more like a functional language, they are Action<T>, Func<T1, T2, ...>. The functional feature let you easily express your algorithm, without using the traditional design pattern. These delegates can be compared with function in javascript, and lamda in other language. For example,


interface IStrategy
{
   void Execute(object o);
}

Using design pattern, we have to write a more code to aggregate different strategies. But using Action<T> is more succinct.


Action<object> oldAction = ... ;//
Action<object> newAction = (o) => { Console.Write("preAction"); oldAction(o); Console.Write("postAction"); }
newAction(o);

If we want to go a step further, we can use function(lamda, delegate) to create functions. For example:


Func<Action<object>, Action<object>> createFunc = (func) => 
{
   return (o) => { 
             Console.Write("preAction"); 
             func(o); 
             Console.Write("postAction"); 
          };
}

Action<ojbect> newAction = createFunc(oldAction);
newAction(o);

Functional language is not new, Javascript is a functional language, and it has been doing this for a long long time. The power functional programming is that you can easily define new function easily, so that you can get interesting result of the new function.

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.

Sep 27, 2009

4 Equals, Reference Type, Value Type

The very fundamental design in .net clr is that type system is classified into two type, reference type and value type. This design decision has profound implication on the .net. One examples is to test the equality between objects.
Basically we have two kinds of comparison, identity comparison(whether two object has the same identity), semantic comparison(whether two object means the same thing, most people refer it as value equality comparison, I use "semantic" because value of reference type is a reference, even the values of reference typed variable are different, it is possible that they mean the same thing in semantics). Since we have the two different type, this makes things complicated. For example, can we compare the "value" of reference type, or can we compare the reference of value type. If there had been only reference type, if there had been no value type, the .net world will be simpler. Why we need two types? This is a deep question, lots of this topics has been covered in a book "CLR via C#". Basically, this a consideration of memory efficiency and performance. What we need to know is that the value of reference type is reference, the value of value type is value.

Reference type identity comparison

To do identity comparison for reference type, we should call Object.ReferenceEquals(objA, objB), or you can use shortcurt operator "==" like "objA == objB". The following source code shows that ReferenceEquals and == operator is the same.
public class Object 
{
   [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
   public static bool ReferenceEquals (Object objA, Object objB) {
       return objA == objB; 
   }
}

If they are the same, why we still need ReferenceEquals, this is because "==" is an operator for object type, if we are not using this method, we can use "(object)a == (object)b".
//you can use
TypeA a;
TypeB b;

Assert.IsTrue(ReferenceEquals(a, b) == ( (object)a == (object)b) );
The "==" means different things for different type value type. What exactly "==" does? For all reference type and all primitive value type, like int, double, enum, it become "ceq" instruction after it is compiled msil. What does "ceq" do? It is clr implementation question, I guess it compare identity equal for reference type and compare value equal for primitive value type. But it means "==" operator for custom value type like struct, which has not default implementation.

Reference type semantic comparison

The default semantic comparison of reference type is identity comparison, because the value of reference type variable is a reference. The default implementation is as follow.
// Returns a boolean indicating if the passed in object obj is
// Equal to this.  Equality is defined as object equality for reference
// types and bitwise equality for value types using a loader trick to 
// replace Equals with EqualsValue for value types).
// 
public virtual bool Equals(Object obj)
{
    return InternalEquals(this, obj);
} 

[MethodImplAttribute(MethodImplOptions.InternalCall)] 
internal static extern bool InternalEquals(Object objA, Object objB);
According the comments, for reference type object, InternalEquals just compare the reference, it does not compare referenced content. The following code shows this behavior.
static void Main(string[] args)
{
    Customer c1 = new Customer { Name = "fred" };
    Customer c2 = new Customer { Name = "fred" };
    Customer c3 = c1;
    
    Console.WriteLine(object.ReferenceEquals(c1, c2)); //False
    Console.WriteLine(object.ReferenceEquals(c1, c3));  //True
    
    Console.WriteLine(c1 == c2); //False
    Console.WriteLine(c1 == c3); //True

    Console.WriteLine(c1.Equals(c2));  //False, event the reference content is same
    Console.WriteLine(c1.Equals(c3));  //True
}

 public class Customer
 {
     public string Name { get; set; }
 }
But sometimes, we want to change this semantics. In our case, we can say if the name of customer is the same, regardless their identity. So we can override the instance Equals method like the following.
public class Customer
    {
        public string Name { get; set; }

        public override bool Equals(object obj)
        {
            var c = obj as Customer;
            if (c == null)
            {
                return false;
            }
            else
            {
                return this.Name == c.Name;
            }
        }
    }

Value type identity comparison

Can you compare identity of value type variable. "Yes". Should you compare identity of value types variable. "No". The result will always return "False", because object put in different boxes before comparison.
Console.WriteLine(object.ReferenceEquals(1, 1)); // False

Value type semantic comparison

Although you can use "==" operator with primitive value type like System.Int32, but you can not use it with custom value type such as struct before you implement the operator by your self. But you can use object type's instance Equals to do semantic comparison, which use reflection to check content equality like below.
public override bool Equals (Object obj) {
    BCLDebug.Perf(false, "ValueType::Equals is not fast.  "+this.GetType().FullName+" should override Equals(Object)"); 
    if (null==obj) { 
        return false;
    } 
    RuntimeType thisType = (RuntimeType)this.GetType();
    RuntimeType thatType = (RuntimeType)obj.GetType();

    if (thatType!=thisType) { 
        return false;
    } 

    Object thisObj = (Object)this;
    Object thisResult, thatResult; 

    // if there are no GC references in this object we can avoid reflection
    // and do a fast memcmp
    if (CanCompareBits(this)) 
        return FastEqualsCheck(thisObj, obj);

    FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 

    for (int i=0; i<thisFields.Length; i++) { 
        thisResult = ((RtFieldInfo)thisFields[i]).InternalGetValue(thisObj,false);
        thatResult = ((RtFieldInfo)thisFields[i]).InternalGetValue(obj, false);

        if (thisResult == null) { 
            if (thatResult != null)
                return false; 
        } 
        else
        if (!thisResult.Equals(thatResult)) { 
            return false;
        }
    }

    return true;
} 
Because the method use reflection to compare, it tends to be slow. So we should always override instance Equals() for your custom value type struct to improve performance.

Comparing objects of unknown type

If we don't know the types of two object, the best bet is to use static method object.Equals(objA, objB). This method check if the identity equal first, then check semantic equality, this if This method is as follow.
public static bool Equals(Object objA, Object objB)
{
    if (objA==objB) {
        return true;
    } 
    if (objA==null || objB==null) {
        return false; 
    } 
    return objA.Equals(objB);
} 
To wrap it, what does this means to me? We can follow the following pseudo code
if (we compare two object of the same type)
{
    if (type is reference type)
    {

        if (we want semantic compare && we have override the objA.Eqauls method)
        {
            objA.Equals(B); 
        }
        else //we just want to identity compare
        {
            always use "objA == objB";
            but object.ReferneceEqual(objA, objB) and objA.Eqauls(objB) do the same thing in this case
        }
    }
    else //type is value type
    {
        if (we want identity compare)
        {
           forget about it, although we can call object.ReferenceEqual(objA, objB)
            it will always return false because of boxing
        }
        else //we should always use semantic compare
        {
            if (type is primitive value type like int)
            {
                x == y // it is compiled to ceq il instruction
            }
            else
            {
                if (you have implment the == operator for this type)
                {
                    use objA == objB
                }
                else
                {
                    use objA.Equels(objB)
                    //if you want more efficent comparison override instece Equals method
                }
            }
        }
    }
}
else //we compare two object of unknown type
 {
    Object.Equals(objA, objB);
 }
For reference type, "==" is enough for a situation, unless you want to change the default semantics comparison. For primitive value type, "==" is enough for most situations. For struct, you are encourage to override default semantics comparison obj.Equals() for performance, although not mandatory, and use obj.Equals for comparison.

Jul 28, 2009

Raise Event from outside

Normally raising event is the responsibility side of a class, but in workflow there is a need to raise event from outside. Here is the code that allow client dynamically raise event externally.

class EventRaiser
    {
        static BindingFlags getEventFlags = BindingFlags.Instance | BindingFlags.NonPublic;
        private object _eventObject;
        private MethodInfo _eventInvoker;

        public EventRaiser(object hostingObject, string eventName)
        {
            FieldInfo fieldInfo = hostingObject.GetType().GetField(eventName, getEventFlags);
            _eventObject = fieldInfo.GetValue(hostingObject);
            _eventInvoker = _eventObject.GetType().GetMethod("Invoke");
        }

        public void RaiseEvent(WorkflowEventArguementBase argument)
        {
            _eventInvoker.Invoke(_eventObject, new object[] { null, argument });
        }
    }

Apr 28, 2008

Enumerating AppDomains

Here is section of code that can list all AppDomain of the current process

using System.Runtime.InteropServices;       // for domain enum
using mscoree;                              // for domain enum. Add the following as a COM reference - C:\WINDOWS\Microsoft.NET\Framework\vXXXXXX\mscoree.tlb
namespace MyNS
{

    public class ListProcessAppDomains
    {
        public static IList GetAppDomains()
        {
            IList _IList = new List();
            IntPtr enumHandle = IntPtr.Zero;
            CorRuntimeHostClass host = new mscoree.CorRuntimeHostClass();
            try
            {
                host.EnumDomains(out enumHandle);
                object domain = null;
                while (true)
                {
                    host.NextDomain(enumHandle, out domain);
                    if (domain == null) break;
                    AppDomain appDomain = (AppDomain)domain;
                    _IList.Add(appDomain);
                }
                return _IList;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return null;
            }
            finally
            {
                host.CloseEnum(enumHandle);
                Marshal.ReleaseComObject(host);
            }
        }
    }
}

Jan 29, 2008

Property vs Method

  • If a property accessor has abserable side effects, implment a method instead of a property.
  • If the implementation of a property is considerably more expensive than that of a field, implementation a method instead. When you expose a property, you suggest to users that making frequent calls to it is acceptable. When you implement a method, you suggest to users that they save an reuse a returned value if they repeately need it.
  • If some properties require a user to set them in a predefined order, implement those properties as methods. In general, you should design your components so that properties can be set in any order.
  • If you need a write-only property, implement a method instead.

Jun 20, 2007

delegate asyn call

class Program
{
            static void Main()
            {
            AsyncCallback callback = new AsyncCallback(Callback);
            Func f = Console.ReadLine;
            f.BeginInvoke(Callback, null);
            Thread.Sleep(Timeout.Infinite);
            }

            static void Callback(IAsyncResult result)
            {
            AsyncResult async = result as AsyncResult;
            Func f = async.AsyncDelegate as Func;
            string s = f.EndInvoke(result);
            Console.WriteLine(s);
            Environment.Exit(0);
            }
}