Tuesday, 18 April 2017

Can private constructor parameterized and their uses?

Yes,It uses in Singleton and Factory design pattern.

Singleton - 
A singleton object. You use a member called Instance to access the instance where you create a new one only if it does not yet exists.
public class Singleton{
    private static Singleton instance;

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

Factory
Private constructors can be useful when using a factory pattern (in other words, a static function that's used to obtain an instance of the class rather than explicit instantiation).
public class MyClass
{ 
    private static Dictionary<object, MyClass> cache = 
        new Dictionary<object, MyClass();

    private MyClass() { }

    public static MyClass GetInstance(object data)
    {
        MyClass output;

        if(!cache.TryGetValue(data, out output)) 
            cache.Add(data, output = new MyClass());

        return output;           
    }
}
Pseudo-Sealed with Nested Children
Any nested classes that inherit from the outer class can access the private constructor.
For instance, you can use this to create an abstract class that you can inherit from, but no one else (an internal constructor would also work here to restrict inheritance to a single assembly, but the private constructor forces all implementations to be nested classes.)
public abstract class BaseClass
{
    private BaseClass() { }

    public class SubClass1 : BaseClass
    {
        public SubClass1() : base() { }
    }

    public class SubClass2 : BaseClass
    {
        public SubClass2() : base() { }
    }
}
Base Constructor
They can also be used to create "base" constructors that are called from different, more accessible constructors.
public class MyClass
{
    private MyClass(object data1, string data2) { }

    public MyClass(object data1) : this(data1, null) { }

    public MyClass(string data2) : this(null, data2) { }

    public MyClass() : this(null, null) { }
}

Keep in mind that all C# Class definitions create a ("invisible") default Public Constructor with no parameters.

That default Constructor, when evoked, will set the value of all Class fields to their Type's default values.

In early versions of C#, a Private Class Constructor with no parameters was often used with the Class marked as 'Sealed, and the Class was used as a "host" for a collection of Static methods. This type of Class is referred to as a "Utility Class."

Why was the Class marked 'Sealed: to prevent someone attempting to derive from the Class.

Early versions of C# defined a default Constructor for you, if you did not supply one yourself. So, writing a parameterless Private Constructor was a way to make sure the Class could never be instantiated.

Later versions of C# replaced these awkward constraints with ability to define Static Classes: with a Static Class you no longer had to write a Private Constructor, didn't need to mark them 'Sealed, etc.

Can a Private Constructor have Parameters ? Yes. You might do that if you had some reason to have a level of indirection where there were Private variables (or whatever) in the Class that you never wanted set directly from outside an instance of the Class. 

To implement that you would implement some form of Public Constructor, or Public Method that created an instance of the Class and did accept Parameters, and then call the Private Constructor.

Example : 

public class TestProgram
    {
        private int? A;
        private decimal? B;

        private TestProgram(int? a, decimal? b)
        {
            A = a;
            B = b;
        }

        public TestProgram(int? a1)
            : this(a1, null)
        {


        }

        public TestProgram(decimal? b1)
            : this(null, b1)
        {


        }
       
    }

    public class TestProgram1 : TestProgram
    {
        public TestProgram1(int i, decimal? j)
            : base(i)
        {
        
        }
        public TestProgram1(int? i, decimal j)
            : base(j)
        {

        }

        static void Main(string[] args)
        {
            TestProgram1 p = new TestProgram1(10,null);
            TestProgram1 p1 = new TestProgram1(null,33);
            Console.ReadLine();
        }

    }