C# Static Class

Static Members

सामान्‍यत: जब हम कोई Class Define करते हैं, तो उस Class के जो भी Object Create करते हैं, उस हर Object के स्वयं के Fields होते हैं, जिनमें केवल उसी Object के Data Stored रहते हैं। उदाहरण के लिए यदि हम अपने पिछले Program को ही निम्नानुसार Modify करें, जिसमें Main() Method में एक नहीं बल्कि 3 Box Type Object Create किए गए हों:

// File Name: BoxClassMemberAccess.cs
using System;

namespace CSharpClass{
    class Box {
        double width;
        double height;
        double length;

        private double Volume() {
            double volume;
            volume = length * height * width;
            return volume;
        }

        public void SetSize(double h, double l, double w) {
            height = h;
            width = w;
            length = l;
        }

        public void Display(){
            Console.WriteLine("Height: " + height);
            Console.WriteLine("Width: " + width);
            Console.WriteLine("Length: " + length);
            Console.WriteLine("Volume: " + Volume());
        }
    }

    class UsingBoxClass{
        static void Main(String[] arg) {
            Console.WriteLine("CPU Cabinet Information");
            Box cpuCabinet = new Box();
            cpuCabinet.SetSize(10, 20, 30);
            cpuCabinet.Display();

            Console.WriteLine("\nHard Disk Information");
            Box hardDisk = new Box();
            hardDisk.SetSize(5, 8, 10);
            hardDisk.Display();

            Console.WriteLine("\nMonitor Information");
            Box monitor = new Box();
            monitor.SetSize(10, 3, 20);
            monitor.Display();
        }
    }
}

// Output:
CPU Cabinet Information
   Height: 10
   Width: 30
   Length: 20
   Volume: 6000

Hard Disk Information
   Height: 5
   Width: 10
   Length: 8
   Volume: 400

Monitor Information
   Height: 10
   Width: 20
   Length: 3
   Volume: 600

तो जैसाकि इस Program के Output द्वारा हम समझ सकते हैं कि तीन अलग Object Create करने पर तीनों ही Objects के Data भी Memory में अलग-अलग Store होते हैं। क्योंकि तीनों Object के Data को Store करने के लिए अलग-अलग Fields Create होते हैं और इन Fields के Data को Access व Manipulate करने के लिए हमें इनके Object के साथ Dot Operator का प्रयोग करके Fields को Specify करना जरूरी होता है।

यानी इस Program में Box Type के तीन Object Create करने का मतलब ये है कि हम एक ही Blueprint के आधार पर एक जैसे तीन घर बना रहे हैं और हर घर में अलग-अलग तरह का सामान Store कर रहे हैं, जिन्हें Access व Manipulate करने के लिए हमें घर के नाम के साथ उस Data को नाम भी Specify करना होता है, जिसे हम Access करना चाहते हैं।

Static Fields

कई बार किसी Class में हमें ऐसे Data Members Define करने की जरूरत होती है, जिनका उस Class के Object के साथ Directly कोई सम्बंध नहीं होताए बल्कि Class के साथ सम्बंध होता है।

उदाहरण के लिए मानलो कि हमें ये जानना हो कि पिछले Program में किसी Specific समय पर कुल कितने Objects Create हुए हैं। तो इस जरूरत को पूरा करने के लिए हम Class में count नाम का एक और Data Member Create नहीं कर सकते, क्योंकि यदि हम ऐसा करते हैं, तो Box Type के Create होने वाले हर Member में Height, WidthLength के साथ Count नाम का एक और Field Create हो जाएगा, जिसमें अलग-अलग Data Store किया जा सकता है।

जबकि किसी Class के कुल कितने Objects Create हुए हैं, ये बात उस Class के सभी Objects के लिए Common होना चाहिए। इसलिए किसी Class के सभी Objects के लिए जब हमें किसी Common Data Member को Specify करना हो, तो हमें Create किए जाने वाले Data Member के साथ static Keyword का प्रयोग करके उस Data Member को Object Level नहीं बल्कि Class Level Data Member के रूप में Declare करना पडता है।

किसी Class के एक static प्रकार के Data Member को बिना उस Class के किसी Object को Create किए हुए भी Directly Access कर सकते है। इसीलिए Main() Method को static रखा जाता है, क्योंकि एक static Method को जिस Class में Declare किया जाता है, उस Class के किसी Object को Create करने से पहले भी उस Class के इस static Method को Call किया जा सकता है।

किसी Class के जिन Instance Variables को static Declare किया जाता है, वे एक प्रकार से Global Variables की तरह व्‍यवहार करने लगते हैं, इसलिए जब उस Class के Object Create किए जाते हैं, तब हर Object के लिए सभी Non-Static Data Members की Copy तो Create होती है, लेकिन static Data Members की Copy Create नहीं होती है।

यानी उस पूरी Class के सभी Objects के लिए static Data Member Common रूप से Use होता है और उस Class के सभी Objects static Data Member को समान रूप से Share करते हैं। इसलिए अब यदि हम ये जानना चाहें कि हमने Current Statement तक Box Class के कितने Objects Create किए हैं, तो हम हमारे पिछले Program को निम्नानुसार तरीके से Modify कर सकते हैं:

// File Name: BoxClassMultipleInstanceStaticDataMember.cs
using System;

namespace CSharpClass {
    class Box {
        static double count;
        double width;
        double height;
        double length;

        private double Volume(){
            double volume;
            volume = length * height * width;
            return volume;
        }

        public void SetSize(double h, double l, double w) {
            height = h;
            width = w;
            length = l;
            count++;
        }

        public void Display()  {
            Console.WriteLine("Height: " + height);
            Console.WriteLine("Width: " + width);
            Console.WriteLine("Length: " + length);
            Console.WriteLine("Volume: " + Volume());
            Console.WriteLine("Total Object Created: " + count);
        }
    }

    class UsingBoxClass {
        static void Main(String[] arg) {
            Console.WriteLine("CPU Cabinet Information");
            Box cpuCabinet = new Box();
            cpuCabinet.SetSize(10, 20, 30);
            cpuCabinet.Display();

            Console.WriteLine("\nHard Disk Information");
            Box hardDisk = new Box();
            hardDisk.SetSize(5, 8, 10);
            hardDisk.Display();

            Console.WriteLine("\nMonitor Information");
            Box monitor = new Box();
            monitor.SetSize(10, 3, 20);
            monitor.Display();
        }
    }
}

// Output:
CPU Cabinet Information
   Height: 10
   Width: 30
   Length: 20
   Volume: 6000
   Total Object Created: 1

Hard Disk Information
   Height: 5
   Width: 10
   Length: 8
   Volume: 400
   Total Object Created: 2

Monitor Information
   Height: 10
   Width: 20
   Length: 3
   Volume: 600
   Total Object Created: 3

इस Program में हमने सबसे पहले Data Member के रूप में एक Static Member Create किया है। चूंकि Static Member हमेंशा Class Level होते हैं, इसलिए जिस Class में Declare किए जाते हैं, उस Class के सभी Objects के लिए Common होते हैं। इसलिए पूरी Class का कोई भी Object यदि Static Data Member के मान को Change कर दे, तो Class के सभी Objects के लिए वह Data Member Change हो जाता है।

इसीलिए हमने उपरोक्त Program में जैसे ही नया Box Object Create करके उसकी Height, WidthLength को Value Assign करने के लिए SetSize() नाम के Method को Call किया है, इसी SetSize() Method में हमने count++ Statement द्वारा Count के मान को Increment कर दिया है। ताकि Class का कोई भी Object यदि Class के इस Static Member को Use करके इस बात का पता लगाना चाहे कि Current Class के कितने Objects Create हो चुके हैं, तो वह इस count नाम के Static Data Member को Use करके इस बात का पता लगा सके।

इसीलिए जब हम उपरोक्त Program में Display() Method को Call करते हैं, तो Display() Method में हमने Static Data Member count को भी Display कर दिया है। परिणामस्वरूप जब cpuCabinet नाम का Object Create किया जाता है, तो Output में हमें निम्नानुसार इस बात का Instruction मिलता है कि Current Statement के Execution तक Box Class का कुल एक Object Create हुआ है:

Total Object Created: 1

इसी तरह से जब hardDisk नाम का दूसरा Object Crete किया जाता है, तो Output में हमें निम्नानुसार इस बात का Instruction मिलता है कि Current Statement के Execution तक Box Class के कुल दो Object Create हो चुके हैं:

Total Object Created: 2

जबकि monitor नाम का तीसरा Object Crete किया जाता है, तो Output में हमें निम्नानुसार इस बात का Instruction मिलता है कि Current Statement के Execution तक Box Class के कुल तीन Objects Create हो चुके हैं:

Total Object Created: 3

अत: जब हमें ऐसे Data Members Create करने होते हैं, जो कि Object Level नहीं बल्कि Class Level होते हैं, तब हम ऐसे Data Members को static Keyword का प्रयोग करते हुए Static Data Member की तरह Declare करते हैं।

चूंकि Fields हमेंशा Object Level होते हैं। इसलिए जब हम किसी Object के Field के Data को किसी दूसरी Class में Access करना चाहते हैं, तब Fields को Access करने के लिए हमें हमेंशा Object Name के साथ Dot Operator को Use करते हुए Field के नाम को Specify करना पडता है।

ठीक इसी तरह से Static Data Members हमेंशा Class Level होते हैं। इसलिए जब हम किसी Class के Static Data Member के Data को किसी दूसरी Class में Access करना चाहते हैं, तब Static Field को Access करने के लिए हमें हमेंशा Class Name के साथ Dot Operator को Use करते हुए Static Field के नाम को Specify करना पडता है।

साथ ही हम केवल उसी स्थिति में Class के नाम के साथ Dot Operator का प्रयोग करते हुए External Class में Static Data Member को Access कर सकते हैं, जबकि Static Data Member को public Keyword का प्रयोग करके Public Access में रखा गया हो। लेकिन यदि Static Data Member को private Keyword का प्रयोग करके Private Access में रखा गया हो, तो हम External Class में इस तरह के Data Member को Class Name के साथ Dot Operator का प्रयोग करके Use नहीं कर सकते। जैसे:

File Name: BoxClassStaticDataMemberOutsideClass.cs
using System;

namespace CSharpClass
{
    class Box
    {
        static double count;
        double width;
        double height;
        double length;

        public void SetSize(double h, double l, double w)
        {
            height = h;
            width = w;
            length = l;
            count++;
        }
    }

    class UsingBoxClass
    {
        static void Main(String[] arg)
        {
            Console.WriteLine("CPU Cabinet Information");
            Box cpuCabinet = new Box();
            cpuCabinet.SetSize(10, 20, 30);
            Console.WriteLine("Total Object Created: " + Box.count);

            Console.WriteLine("\nHard Disk Information");
            Box hardDisk = new Box();
            hardDisk.SetSize(5, 8, 10);
            Console.WriteLine("Total Object Created: " + Box.count);

            Console.WriteLine("\nMonitor Information");
            Box monitor = new Box();
            monitor.SetSize(10, 3, 20);
            Console.WriteLine("Total Object Created: " + Box.count);
        }
    }
}

Output:
BoxClassStaticDataMemberOutsideClass.cs(23,54): error CS0122: 'CSharpClass.Box.count' is inaccessible due to its protection level
BoxClassStaticDataMemberOutsideClass.cs(5,18): (Location of symbol related to previous error)
BoxClassStaticDataMemberOutsideClass.cs(28,54): error CS0122: 'CSharpClass.Box.count' is inaccessible due to its protection level
BoxClassStaticDataMemberOutsideClass.cs(5,18): (Location of symbol related to previous error)
BoxClassStaticDataMemberOutsideClass.cs(33,54): error CS0122: 'CSharpClass.Box.count' is inaccessible due to its protection level
BoxClassStaticDataMemberOutsideClass.cs(5,18): (Location of symbol related to previous error)

जबकि Box Class में count नाम के Static Data Member को By Default Private रखा गया है। इसलिए ये Data Member केवल Class के अन्दर ही Directly Accessible है, जबकि Class के बाहर किसी अन्‍य External Class के लिए Box Class का count नाम का Static Data Member पूरी तरह से Inaccessible या Hidden है।

इसीलिए जब हम उपरोक्त Program को Run करते हैं, तो किसी Class के Private Data को Directly Access करने की कोशिश करने के कारण C# Compiler हमें Error Return करता है। लेकिन यदि हम हमारे इसी Program को Modify करते हुए Box Class में Declare किए गए Static Data Member को निम्नानुसार public Keyword के साथ Specify प्रयोग कर दें:

// File Name: BoxClassStaticDataMemberOutsideClassNormalAccess.cs
using System;

namespace CSharpClass
{
    class Box
    {
        public static double count; 
        double width;
        double height;
        double length;

        public void SetSize(double h, double l, double w)
        {
            height = h;
            width = w;
            length = l;
            count++;
        }
    }

    class UsingBoxClass
    {
        static void Main(String[] arg)
        {
            Console.WriteLine("CPU Cabinet Information");
            Box cpuCabinet = new Box();
            cpuCabinet.SetSize(10, 20, 30);
            Console.WriteLine("Total Object Created: " + Box.count);

            Console.WriteLine("\nHard Disk Information");
            Box hardDisk = new Box();
            hardDisk.SetSize(5, 8, 10);
            Console.WriteLine("Total Object Created: " + Box.count);

            Console.WriteLine("\nMonitor Information");
            Box monitor = new Box();
            monitor.SetSize(10, 3, 20);
            Console.WriteLine("Total Object Created: " + Box.count);
        }
    }
}

// Output:
   CPU Cabinet Information
   Total Object Created: 1

   Hard Disk Information
   Total Object Created: 2

   Monitor Information
   Total Object Created: 3

तो जैसाकि Program के Output द्वारा हम समझ सकते हैं कि अब इस Program को Run करने पर हमें Error नहीं बल्कि उपरोक्तानुसार एक उपयुक्त Output प्राप्त होता है।

Lifetime of Static Field

Class Level Static Data Members का Lifetime, Object Level Data Members के Lifetime से थोडा अलग होता है। Object Level Data Member तब Exist होते हैं, जब Object Create किया जाता है। यदि Object Create न किया जाए, तो Data Member उपयोग के लिए Exist व Accessible ही नहीं होते। साथ ही Object को पूरे Program के दौरान जिस Statement में Create किया जाता है, Object के Data Members की Lifetime उसी Statement से शु: होती है।

जबकि Class Level Static Data Members उस समय भी Exist व Accessible होते हैं, जब उस Class का एक भी Instance Create नहीं किया गया होता है, जिसमें उस Static Data Member को Declare किया गया होता है।

Static Methods

Static Fields की तरह ही हम static Keyword का प्रयोग करके Static Methods भी Create कर सकते हैं और Static Fields की तरह Static Methods भी Object Level नहीं बल्कि Class Level होते हैं, जिन्हें किसी Object के साथ नहीं बल्कि Class के नाम के साथ Dot Operator का प्रयोग करके Use किया जाता है।

साथ ही Static Fields की तरह ही Static Methods भी उस समय भी Exist व Accessible रहते हैं, जब Class का एक भी Object Create नहीं हुआ होता है। इसीलिए Main() Method को हमेंशा static Keyword के साथ Define किया जाता है, ताकि Class का कोई भी Object Create न होने की स्थिति में भी .NET Platform का CLR Main() Method को Execute कर सके।

Static Methods की विशेषता ये होती है कि Static Methods किसी दूसरे Normal अथवा Static दोनों प्रकार के Methods को Access कर सकते हैं, लेकिन कोई Normal Method किसी Static Method को Directly Access नहीं कर सकता।

Static Method जब private Access Modifier के साथ Define किया जाता है, तब उसे केवल समान Class के अन्‍य Static Methods ही बिना Dot Operator के साथ Class का नाम Specify किए हुए Directly Access कर सकते हैं।

जबकि यदि Static Method को public Access Modifier के साथ Define किया जाए, तो कोई भी External Class का Object इन Static Method को Class के नाम के साथ Dot Operator का प्रयोग करके Access कर सकता है।

// File Name: StaticStaticMethodSameClass.cs
using System;

namespace CSharpClass
{
    class StaticMethod
    {
        static void Main(String[] arg)
        {
            int total = add(10, 20);
            Console.WriteLine("Total of 10+20: " + total);
        }

        static int add(int x, int y)
        {
            return x + y;
        }
    }
}

// Output:
   Total of 10+20: 30

इस Program में हमें Normal Output इसलिए प्राप्त हो रहा है क्योंकि हमने दो संख्‍याओं को जोडने के लिए निम्नानुसार add() नाम के एक Static Method Define किया है:

static int add(int x, int y)
{
return x + y;
}

और इस Static Method को एक Main() नाम के Static Method में ही निम्नानुसार Statement द्वारा Call किया है:

int total = add(10, 20);

लेकिन यदि हम add() Method को एक Static Method न बनाते, तो जिस Class में add() Method को Define किया गया है, उस Class का Object Create किए बिना हम add() Method को Directly Call नहीं कर सकते, जैसाकि उपरोक्त Statement में किया गया है।

क्योंकि यदि हम add() Method को Static नहीं बनाते तो add() Method तब तक Memory में Exist व उपयोग के लिए Accessible नहीं होताए जब तक कि हम StaticMethod Class का Object Create नहीं करते।

Static Method को जब किसी दूसरी Class के Object के लिए Call किया जाता है, तो उस दूसरी Class में Static Method को किसी दूसरे Static Method के अन्दर ही Call किया जा सकता है। साथ ही इस दूसरी Class में Static Method को Call करते समय पहली Class के नाम के साथ Dot Operator का प्रयोग करते हुए Call किए जाने वाले Static Method को Specify करना होता है। जैसे:

// File Name: StaticStaticMethodSameClass.cs
using System;

namespace CSharpClass
{
    class StaticMethod
    {
        public static int add(int x, int y)
        {
            return x + y;
        }
    }

    class UsingStaticMethod
    {
        static void Main(String[] arg)
        {
            int total = StaticMethod.add(10, 20);
            Console.WriteLine("Total of 10+20: " + total);
        }
    }
}

// Output:
   Total of 10+20: 30

इस Program द्वारा भी हमें पिछले Program जैसा ही Output प्राप्त हो रहा है। लेकिन इस Program में हमने Static Method को public Keyword के साथ StaticMethod नाम की Class में Define किया है, ताकि कोई भी External Class इस Method को Class के नाम के साथ Dot Operator का प्रयोग करके Access कर सके।

चूंकि StaticMethod Class में Defined add() नाम का Method एक Static Method है, अत: StaticMethod Class का Object Create करने से पहले भी ये Method Memory में Exist रहता है।

इसीलिए UsingStaticMethod Class में बिना कोई Object Create किए हुए हम सी/ो ही StaticMethod.add(10, 20); Statement का प्रयोग करते हुए add() नाम के Method को Call कर रहे हैं और Program हमें उपयुक्त Output दे रहा है।

Fields Methods की तरह ही हम Types, Properties, Constructors, Operators Events Members को भी Static Declare कर सकते हैं।

.NET Framework के BCL में बहुत सारी Classes में विभिन्न प्रकार की जरूरतों को पूरा करने के लिए विभिन्न प्रकार के Static Members को Define किया गया है, जिनके बारे में Detailed जानकारी प्राप्त करने के लिए हम Visual Studio के Object Browser Utility द्वारा mscorlinb.dll के System Namespace की Console, Math, Environment GC Classes को Check कर सकते हैं, जो कि .NET Framework की BCL Classes हैं।

C# Static Class

जिस तरह से हम Static Field व Static Methods Define करते हुए अपनी किसी Specific Type की Requirement को पूरा करते हैं, उसी तरह से हम किसी Class को भी static Keyword का प्रयोग करते हुए Static Class के रूप में Define कर सकते हैं और जब हम किसी Class को Static Define करते हैं, तब हम new Operator का प्रयोग करके उस Class का Object Create नहीं कर सकते।

साथ ही एक Static Class में Specify किए जाने वाले सभी Members का Static होना भी जरूरी होता है। लेकिन एक Static Class में यदि कोई Member Static न हो, तो C# Compiler Error Return करता है।

सामान्‍यत: जो Class या Structure केवल Static Functionalities ही Provide करता है, ऐसे Class या Structure को Utility Class या Utility Structure कहा जाता है। इसलिए जब हमें Utility Class बनाना होता है, तब बेहतर यही होता है कि हम Define की जाने वाली Class को ही Static Define कर दें।

Utility Class Specific Type की Requirements को पूरा करने के लिए काफी उपयोगी साबित होते हैं। क्योंकि Static Class में केवल Static Members Constant Data ही हो सकते हैं, इसलिए इन्हें Use करने से पहले Memory Allocate करने की जरूरत नहीं होती। इस Concept को समझने के लिए हम निम्नानुसार एक उदाहरण Program Create कर सकते हैं:

// File Name: StaticClassOrUtilityClass.cs
using System;

namespace CSharpClass
{
    // Static classes can only contain static members!
    static class TimeUtilClass
    {
        public static void PrintTime()
        {
            Console.WriteLine(DateTime.Now.ToShortTimeString());
        }

        public static void PrintDate()
        {
            Console.WriteLine(DateTime.Today.ToShortDateString());
        }
    }

    class UsingStudent
    {
        static void Main(string[] args)
        {
            Console.Write("Today's Date: ");
            TimeUtilClass.PrintDate();

            Console.Write("Current Time: ");
            TimeUtilClass.PrintTime();

            // Compiler error! Can't create static classes!
            // TimeUtilClass u = new TimeUtilClass ();
        }
    }
}

// Output:
   Today's Date: 6/28/2013
   Current Time: 12:10 PM

इस Program में हमने TimeUtilClass को एक Utility Class यानी Static Class के रूप में Define किया है, इसलिए Main() Method में हमें इस Class का Object Create करने की जरूरत नहीं है।

जबकि यदि हम इस Class का Object Create करने की कोशिश करते हैं, तो Compiler हमें Compile Time Error Return करते हुए ऐसा करने से रोकता है क्योंकि हम Static Class का Direct Object Create नहीं कर सकते।

लेकिन चूंकि हमने TimeUtilClass को एक Static Class बनाया है, इसलिए Main() Method में हम इस Class में Defined Methods को Class के नाम के साथ Dot Operator का प्रयोग करते हुए Call कर सकते हैं, जैसाकि हमने हमारे उपरोक्त Program में निम्नानुसार किया है:

TimeUtilClass.PrintDate();
. . .
TimeUtilClass.PrintTime();

परिणामस्वरूप जब ये Codes Run होते हैं, तो हमें वही Output प्राप्त होता है, जो उपरोक्त Program में दिखाई दे रहा है।

Constant Members

जिस तरह से हम किसी Local Constant को Declare करते हैं, उसी तरह से const Keyword का प्रयोग करके हम किसी Constant Data Member को भी Declare कर सकते हैं।

साथ ही जिस तरह से हम किसी Local Constant को एक बार Declare करने के बाद नया मान Assign नहीं कर सकते हैं, ठीक उसी तरह से किसी Data Member को Constant की तरह Declare करने के बाद भी हम उसे नया मान Assign नहीं कर सकते। जबकि यदि हम ऐसा करने की कोशिश करते हैं, तो C# Compiler Error Trigger करता है और किसी Constant को Reassign करने से रोकता है।

Constant Data Members हालांकि Local Constant की तरह होते हैं, लेकिन ये Static Data Member की तरह व्‍यवहार करते हैं। यानी Constant Data Members Class Level होते हैं और Class के सभी Objects के लिए Common होते हैं, भले ही उस Class का एक भी Object Create न किया गया हो।

Constant Data Members स्वयं Memory में Space Reserve नहीं करते, बल्कि C/C++ के #define की तरह Compile Time में Compiler द्वारा सभी Constants Symbols को Actual मानों द्वारा Replace कर दिया जाता है।

चूंकि C# में Constant Data Member एक प्रकार से Static Data Member की तरह ही Behave करते हुए Class के सभी Objects के लिए Common होता है, इसलिए किसी Constant Data Member को C# में Static Data Member की तरह Declare नहीं किया जा सकता।

यानी यदि हम किसी Class में निम्नानुसार Statement द्वारा किसी Constant Data Member के साथ static Keyword Specify करें, तो Compiler हमें Error देते हुए ऐसा करने से रोकेगा:

class Program
{
public static const PI = 3.1415;            // Error: can’t declare a constant as static
                . . .
}

C# in Hindiये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

C#.NET in Hindi | Page:908 | Format: PDF

BUY NOW GET DEMO REVIEWS