C# (C Sharp) Unified Type System: Reference Types

Reference types form part of unified type system. They aim at providing referential identification for instances. In value types, when two value type variables have the same data then those value types are said to be identical. But in reference types irrespective of the data equivalence, the two instances are said to be different. Reference type variables do not directly contain the data.

Instead they hold the address where the data is put up. Data will be available in a particular address of the managed heap. All reference type variables are implicitly assigned with the value null. Accessing reference type variables that are not explicitly initialized will throw null pointer exception.

Reference Types supported by C# are:

• Class
• String
• Interface
• Delegate

This article will give you an introduction on these reference types.


Class is a data structure that is used to establish encapsulation and other object oriented behavior. Class has members that can either be properties or methods accessing those properties. Each class and its members have its visibility based on the modifier defined. Here is a simple class:

public class testClass {
public int prop1;
public int getProp1( ) {
return prop1;
public void setProp1(int prop1) {
this.prop1 = prop1;

This class has a global visibility. It is visible across all packages since the modifier public is used. This class has a property prop1 and two methods to set and get values from it. If you want to access members from outside the class, then you have to create instances of the class.

Each instance of the class will be declared and accessed using a reference type variable. In the example given below, an object of testClass is created:
public class testClass1{
public static void Main( ){
testClass obj1 = new testClass( );
int value = obj1.getProp1( );

In this example, obj1 is a reference type variable pointing to an instance of testClass. Using this reference type variable you can access members of testClass. Each instance created has its parent class to be System.Object either directly or as the root class in the inheritance tree. Not just instances, any variable created for any type will be derived from System.Object.


Rather than a separate type, even String forms part of a class. If you want to record a collection of characters in one single data type then you can use System.String class. This class cannot be inherited. That’s why it is one among the sealed classes. Here is a simple example to demonstrate the usage of String class:

public class testString( ) {
public static void Main( ) {
string sampleString1 = “This is a sample string”;
string sampleString2 = “This is something else”;
if(sampleString1.Equals(sampleString2)) {
Console.WriteLine(“sampleString1 and sampleString2 are equal”);
Console.WriteLine(“sampleString1 and sampleString2 are not equal”);
Console.WriteLine(“{0}”, sampleString1.ToUpper();


This example illustrates only two methods of String class. There are all together 44 methods available in System.String class. Some of them are: Clone, Concat, Copy, GetHashCode, ToLower, Split, Trim.


If you want to derive characteristics of a class into another, you can achieve it using inheritance. What if you want to derive characteristics from two classes? You cannot do it. This is because a class can be inherited from only one class.

However, you can achieve this functionality using interface. Interface is an abstract representation which has properties and methods. These members will only be declared but not defined. Class that implements this interface has to define all members of the interface. A class has a liberty to implement more than one interface. Here is an example in which a class is implementing more than one interface:

public interface ITestInterface1{
int method1( );
public interface ITestInterface2{
void method2( );
class implClass : ITestInterface1, ITestInterface2 {
int member1 = 10;
int method1( ) {
return member1;
void method2( ) {
Console.WriteLine(“Implementing ITestInterface2.method2”);
public static void Main( ) {
implClass obj1 = new implClass( );
Console.WriteLine(“{0}”, obj1.method1( ));
obj1.method2( );


If you have to call an anonymous method or call a method that can be determined only at run time and not at compile time, then you can wrap them inside a delegate and declare a reference type for it. Delegates are mainly used for handling events. Consider the following example:

public delegate void testDelegate( );
class sampleDelegateUsage {
public static void testMethod1() {
console.WriteLine(“Executing testMethod1”);

public static void Main( ) {
testDelegate deleg1 = new testDelegate(testMethod1);
deleg1( );

Here a delegate deleg1 is wrapping a method called testMethod1. Output of this code will be: Executing testMethod1

| All about Conceptual Analysis on .NET Remoting | Building desktop applications in .Net | Building Distributed Applications Efficiently Using .Net Remoting | C# (C Sharp) Unified Type System: Reference Types | C# (C Sharp) Unified Type System: Value Types | Data access in .Net | Delegates Vs Interfaces in C# (C Sharp) | How is Integration between Java and .NET Achieved | How is Versioning Achieved in C# (C Sharp) | Implementing Authorization and authentication in ASP.net | Implementing design patterns in .Net | List of Query Keywords in C# (C Sharp) |

“Amazon and the Amazon logo are trademarks of Amazon.com, Inc. or its affiliates.”

| Privacy Policy for www.dotnet-guide.com | Disclosure | Contact |

Copyright - © 2004 - 2024 - All Rights Reserved.