C#: Interface

Interface

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Monad;
using System.Collections;

namespace Monad
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = GenericAdd<int, int, Maybe<int>, Maybe<int>>(Maybe<int>.Nothing, 2.ToMaybe());

            if (result.HasValue)
                Console.WriteLine(result);
            else
                Console.WriteLine("Nothing");

            var a = TMonad<MyList<int>, MyList<Tuple<int, int>>, int, Tuple<int, int>>.Bind;
            a = TMonad<MyList<int>, MyList<Tuple<int, int>>, int, Tuple<int, int>>.Bind;
            var result2 = GenericAdd<int, Tuple<int, int>, MyList<int>, MyList<Tuple<int, int>>>(new MyList<int> { 1, 2, 3 }, new MyList<int> { 4, 5, 6 });

            foreach (var item in result2)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }

        private static CB GenericAdd<A, B, CA, CB>(CA ai, CA bi)
            where CA : IGeneric<A>
            where CB : IGeneric<B>
        {
            var result = TMonad<CA, CB, A, B>.Bind(ai, a =>
            {
                return TMonad<CA, CB, A, B>.Bind(bi, b =>
                {
                    return TMonad<CB, CB, B, B>.Return(TAdder<A, B>.Add(a, b));
                });
            });
            return result;
        }
    }

    public interface IGeneric<T> { }

    public class TMonad<CA, CB, A, B>
        where CA : IGeneric<A>
        where CB : IGeneric<B>
    {
        public static Func<CA, Func<A, CB>, CB> Bind;
        public static Func<A, CA> Return;

        static TMonad()
        {
            TMonad<Maybe<A>, Maybe<B>, A, B>.Bind = MaybeMonad<A, B>.Bind;
            TMonad<Maybe<A>, Maybe<B>, A, B>.Return = MaybeMonad<A, B>.Return;

            TMonad<MyList<A>, MyList<B>, A, B>.Bind = ListMonad<A, B>.Bind;
            TMonad<MyList<A>, MyList<B>, A, B>.Return = ListMonad<A, B>.Return;
        }
    }

    public class TAdder<A, B>
    {
        public static Func<A, A, B> Add;

        static TAdder()
        {
            TAdder<int, int>.Add = (x, y) => x + y;
            TAdder<String, string>.Add = (x, y) => x + y;
            TAdder<int, Tuple<int, int>>.Add = (x, y) => new Tuple<int, int>(x, y);
        }
    }

    public class MyList<T> : List<T>, IGeneric<T>
    {
        public MyList()
        {}

        public MyList(List<T> l)
        {
            this.AddRange(l);
        }
    }

    public class Maybe<T> : IGeneric<T>
    {
        public readonly static Maybe<T> Nothing = new Maybe<T>();
        public T Value { get; private set; }
        public bool HasValue { get; private set; }

        Maybe()
        {
            HasValue = false;
        }
        public Maybe(T value)
        {
            Value = value;
            HasValue = true;
        }
    }

    public class MaybeMonad<A, B>
    {
        public static Maybe<B> Bind(Maybe<A> a, Func<A, Maybe<B>> f)
        {
            if (a.HasValue) return f(a.Value);
            else return Maybe<B>.Nothing;
        }

        public static Maybe<A> Return(A a)
        {
            return a.ToMaybe();
        }
    }

    public class ListMonad<A, B>
    {
        public static MyList<B> Bind(MyList<A> a, Func<A, MyList<B>> f)
        {
            return new MyList<B>(a.SelectMany(x => f(x)).ToList());
        }

        public static MyList<A> Return(A a)
        {
            return new MyList<A> { a };
        }
    }

    public static class Helpers
    {
        public static Maybe<T> ToMaybe<T>(this T value)
        {
            return new Maybe<T>(value);
        }
    }
}

interface

C#: Getting the dates from file names

Getting the dates from file names.

using System.Linq;
using System.Collections.Generic;
class Test
{
    static void Main()
    {
        var items = new List<string>() {
                "foo_20120212",
                "foo_20120213",
                "foo_20120214",
                "foo_20120215",
                "baz_20120212",
                "baz_20120213",
                "baz_20120214",
                "baz_20120215"};

        var v = items.Select(a => a.Insert(a.Length - 2, "/"))
                                .Select(b => b.Insert(b.Length - 5, "/"))
                                .Select(c => new { date = c.Split('_')[1], str = c.Replace("/", "") })
                                .Select(d => new { date = String.Concat(d.date.Split('/').Reverse()), str = d.str })
                                .Select(e => new { date = e.date.Insert(e.date.Length - 4, "/"), str = e.str })
                                .Select(f => new { date = f.date.Insert(f.date.Length - 7, "/"), str = f.str })
                                .Select(g => new { date = DateTime.Parse(g.date), str = g.str })
                                .OrderByDescending(h => h.date).ToList();

        v.ForEach(x => Console.WriteLine(String.Format("date: {0}, str: {1}", x.date, x.str)));
        Console.ReadKey();
    }
}

date

C#: Get and Set

This entry is part 71 of 71 in the series C#

A get and set example:

public class BaseClass 
{
	private string _name;
	public string Name
	{
		get 
		{
			return _name; 
		}
		set 
		{
			_name = value; 
		}
	}
}

public class DerivedClass : BaseClass 
{
	private string _name;
	public new string Name   // Notice the use of the new modifier
	{
		get 
		{
			return _name; 
		}
		set 
		{
			_name = value; 
		}
	}
}

public class MainClass 
{
	public static void Main() 
	{
		DerivedClass d1 = new DerivedClass();
		d1.Name = "John";  // Derived class property
		Console.WriteLine("Name in the derived class is: {0}",d1.Name);
		((BaseClass)d1).Name = "Mary"; // Base class property
		Console.WriteLine("Name in the base class is: {0}",
			((BaseClass)d1).Name);   
	}
}

getset

C#: Generic swap functions

This entry is part 70 of 71 in the series C#

Generic swap functions

namespace Test
{
	class Program
	{
		
		public static void Swap<T> (T a, T b)
		{
			var temp = a;
			a = b;
			b = temp;
		}

		public static void Swap<T> (ref T a, ref T b)
		{
			var temp = a;
			a = b;
			b = temp;
		}

		public static void SwapValue (SwapTest a, SwapTest b)
		{
			var temp = a.Value;
			a.Value = b.Value;
			b.Value = temp;
		}

		public class SwapTest
		{
			public string Value { get; set; }
		}

		static void Main ()
		{
			var a = new SwapTest { Value = "a" };
			var b = new SwapTest { Value = "b" };
			Swap (a, b);
			Console.WriteLine ("Value a: " + a.Value + " |  Value b: " + b.Value); 
			//output: Value a : a | Value b : b  

			a = new SwapTest { Value = "a" };
			b = new SwapTest { Value = "b" };
			Swap (ref a, ref b);
			Console.WriteLine ("Ref Value a: " + a.Value + " |  Ref Value b: " + b.Value); 
			//output: Ref Value a : b | Ref Value b : a 

			a = new SwapTest { Value = "a" };
			b = new SwapTest { Value = "b" };
			SwapValue (a, b);
			Console.WriteLine ("Swap Value a: " + a.Value + " |  Swap Value b: " + b.Value); 
			//output: Swap Value a : b | Swap Value b : a 
			Console.Read ();
		}
	}
}

swap

What are Covariance and ContraVariance in C#4.0?

Introduction

In this whole artcile we will learn all about Covariance and Contracvariance, what were the issues with development before these two.

Definition

These two Covariance and Contravariance have been introduced in C#4.0. As per msdn
we simply define:

covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves
assignment compatibility and contravariance reverses it.

In simple words, we can say Covariance and Contravariance are the polymorphism extensions to array types, delegate types, and generic type (we will see in coming sections).

Issue before these two

What were the issues before the invension of these two. lets consider following example:

class GrandFather
{

}

class Son : GrandFather
{

}

class GrandSon : GrandFather
{

}

you can see we are using inheritance, GrandFather is a parent class to Son and GrandSon. As per polymorphism we can do this:

GrandFather father = new Son();
father   = new GrandSon();

if above statement is correct then following statement also should be correct:

//will throw exception prior to version 4.0
IEnumerable<GrandFather> fathers = new List<Son>();

isn’t it somehow violate polymorphism 🙂

Now, try this in C#4.0

//will work fine with version 4.0
IEnumerable<GrandFather> fathers = new List<Son>();

in above IEnumerable, an out parameter of type T.

Consider following method is in the class:

static void ParentalObject(object o)
{
	//method signature
}
Action<Object> actionObj = ParentalObject;

and we can assign this instantiated object to

Action<Object> actionObj1 = actionObj;

intatiated object with more derived type arguments

Array Covariance

This is nothing but implicit conversion of an array of a more derived type to an array of a less derived type. Unfortunately this is not type safe.

object[] strArray = new string[10];
strArray[0] = 1; //will throw runtime exception

In above example, our object array is of string type but we are assigning integer value to one of its element, it will not throw any compile-time exception
but, it will throw runtime exception.

[h2>Delegate Covariance

This type of Covariance is also called as method group variance. From msdn
you can assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept
parameters that have less derived types (contravariance) than that specified by the delegate type. This includes both generic and non-generic delegates.

static string Parental()
{
	return "Grandfather name is: Lala Bhagwan Das";
}

and see following:

Func<object> parentalLambda = () => Parental(); //lambda expression
Func<object> parentalFunc = Parental; //Grouped

Now, consider following method in a class:

static string ParentalObject(object obj)
{
	//method signature
}

Contravariance. A delegate specifies a parameter type as string, but can assign a method that takes an object.

Action<String> parentalDel = ParentalObject;
[h2>Variance in Generic Type Parameters

As per msdn you can enable implicit conversion between delegates, so that generic delegates that have different types specified by
generic type parameters can be assigned to each other, if the types are inherited from each other as required by variance.

To enable implicit conversion, you must explicitly declare generic parameters in a delegate as covariant or contravariant by using the in or out keyword.

Consider below code:

delegate T ParentalGenericDelegate<out T>();

In above we declated type T as a contravariant by using the out keyword.

ParentalGenericDelegate<string> grandFatherName = () => "Grandfather name is: Lala Bhagwan Das";

Above, shows how we can create a delegate which is having generic type parameter.

ParentalGenericDelegate<object> anotherGenericDelegate = () => grandFatherName;

Above statement is correct, we can assign delegates to each-other and type T is declared as covariant.

Conclusion

We can say Covariance and Contravariance are the polymorphism extensions to array types, delegate types, and generic type (we will see in coming sections).