Saturday, November 13, 2010

Accessor Accessibility Domain


Accessor Accessibility Domain


In couple of interviews the question is asked that can we set different accessors for the same property. So the answer is:

By default these accessors have the same visibility, or access level: for the property or indexer. For more information, see accessibility levels. However, it is sometimes useful to restrict access to one of these accessors. Mostly, for restricting the accessibility of the set accessor, when get accessor is publicly accessible. However, this Restriction is only supported by C# Language. not by VB, or C++ or F# and JScript


Example


The following example contains three classes, MyBaseClass, MyDerivedClass, and MyMainClass. There are two properties in the MyBaseClass, Name and Id on both classes. The example exhibits how the property Id on MyDerivedClass can be hidden by the property Id of MyBaseClass when we use a restrictive access modifier such as protected or private. When we assign values to this property, the property on the MyBaseClass class is called instead. Replacing the access modifier by public will make the property accessible.
The example exhibits how a restrictive access modifier, such as private or protected, on set accessor of Name property in MyDerivedClass prevents access to accessor and generates an error when we assign to it.

////MyBaseClass
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class MyBaseClass
    {
        private string name = "Name-BaseClass";
        private string id = "ID-BaseClass";

        public string Name
        {
            get { return name; }
            set { }
        }

        public string Id
        {
            get { return id; }
            set { }
        }
    }


}

//MyDerivedClass
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class MyDerivedClass : MyBaseClass
    {
        private string name = "Name-DerivedClass";
        private string id = "ID-DerivedClass";

        new public string Name
        {
            get
            {
                return name;
            }

            // Using "protected" would make the set accessor not accessible.
            set
            {
                name = value;
            }
        }

        // Using private on the following property hides it in the Main Class.
        // Any assignment to the property will use Id in BaseClass.
        new private string Id
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }
    }


}

//MyMainClass
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class MyMainClass
    {
        static void Main()
        {
            MyBaseClass b1 = new MyBaseClass();
            MyDerivedClass d1 = new MyDerivedClass();

            b1.Name = "Meetu";
            d1.Name = "Gaurav";

            b1.Id = "Meet";
            d1.Id = "Gaur";  // The BaseClass.Id property is called.


            System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);
            System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }

}


/* Output:
   Base: Name-BaseClass, ID-BaseClass
    Derived: Gaurav, ID-BaseClass
*/




Comments


Notice that if you replace the declaration new private string Id by new public string Id, you get the output:
Name and ID in the base class: Name-BaseClass, ID-BaseClass
Name and ID in the derived class: Gaurav, Gaur

How to: Implement a Lightweight Class with Auto-Implemented Properties


in my previous article i have discussed about Auto implemented properties. In this example I will shows how we can create an immutable lightweight class which will serve the purpose only to encapsulate a set of auto-implemented properties. We can use this kind of construct in place of a struct when we must use reference type semantics.
Note that in case of auto-implemented properties, both a get and set accessor are required. We make the class immutable by declaring the set accessors as private(Yes this is possible in C#). However, declaring a private set accessor, we cannot use an object initializer to initialize the property. For this we must use a constructor or a factory method.
Example
The following example shows two ways to implement an immutable class that has auto-implemented properties. The first class uses a constructor to initialize the properties, and the second class uses a static factory method.
//ClassA
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LightweightClass
{
    // This is an immutable class. Once an object is created, it cannot be modified outside the class. It only uses its constructor to initialize properties.
    class ClassA
    {
        // Read-only properties.
        public string Property1 { get; private set; }
        public string Property2 { get; private set; }

        // Public constructor.
        public ClassA(string Value1, string Value2)
        {
            Property1 = Value1;
            Property2 = Value2;
        }
    }
}


//ClassB
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LightweightClass
{
    // This is an immutable class. Once an object is created, it cannot be modified outside the class. It only uses its constructor or the public Factory Mthod to initialize properties.
    public class ClassB
    {
        // Read-only properties.
        public string Property1 { get; private set; }
        public string Property2 { get; private set; }

        // Private constructor.
        private ClassB(string Prop1, string Prop2)
        {
            Property1 = Prop1;
            Property2 = Prop2;
        }

        // Public factory method.
        public static ClassB CreateObject(string prop1, string prop2)
        {
            return new ClassB(prop1, prop2);
        }
    }


}

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

namespace LightweightClass
{
    public class Program
    {
        static void Main()
        {
            // Some simple data sources.
            string[] names = {"Meetu Choudhary","Gaurav Arora", "Prabhjeet Gill",
                              "Nikita Rathi", "Manpreet Kaur"};
            string[] addresses = {"29 Jaipur", "12 Gaziabad.", "678 1st Ave",
                                  "12 Tonk", "89 Et. Mumabi"};

            // Simple query to demonstrate object creation in select clause.
            // Create objects of ClassA by using a constructor.
            var query1 = from i in Enumerable.Range(0, 5)
                         select new ClassA(names[i], addresses[i]);

            // List elements cannot be modified by client code.
            var list = query1.ToList();
            Console.WriteLine("Using Constroctor");
            foreach (var contact in list)
            {
                Console.WriteLine("{0}, {1}", contact.Property1 , contact.Property2 );
            }

            // Create ClassB objects by using a static factory method.
            var query2 = from i in Enumerable.Range(0, 5)
                         select ClassB.CreateObject(names[i], addresses[i]);

            // Console output is identical to query1.
            var list2 = query2.ToList();
            Console.WriteLine("Using Factory Method");
            foreach (var contact in list2)
            {
                Console.WriteLine("{0}, {1}", contact.Property1, contact.Property2);
            }
            // List elements cannot be modified by client code. this will gentrate the error
            // CS0272:
            // list2[0].Name = "Eugene Zabokritski";

            // Keep the console open in debug mode. to check
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

Output

Using Constroctor
Meetu Choudhary, 29 Jaipur
Gaurav Arora, 12 Gaziabad.
Prabhjeet Gill, 678 1st Ave
Nikita Rathi, 12 Tonk
Manpreet Kaur, 89 Et. Mumabi
Using Factory Method
Meetu Choudhary, 29 Jaipur
Gaurav Arora, 12 Gaziabad.
Prabhjeet Gill, 678 1st Ave
Nikita Rathi, 12 Tonk
Manpreet Kaur, 89 Et. Mumabi
Press any key to exit.

Subscribe via email

Enter your email address:

Delivered by FeedBurner

MSDotnetMentor

MSDotnetMentor My Website http://msdotnetmentor.com

Blog Archive