C# Class vs Struct vs Static Class and Interfaces

CipherIS
CipherIS used Ask the Experts™
on
What is the difference between a class, struct, and static class?

How would you decide to use a interface?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
AndyAinscowFreelance programmer / Consultant

Commented:
For classes see:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/classes

For static class see (the first paragraph compares static with non-static classes):
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members

For struct see:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/struct

When to use an interface?  
That acts as a template to 'force' any classes using that interface to implement methods or functions with a common declaration.  eg. an interface might include void Sort() - so any class using that interface has to implement a method called Sort that returns void and takes no parameters.

Author

Commented:
Thanks.

How would you decide to create a class versus struct versus static class?
Fernando SotoRetired
Distinguished Expert 2017

Commented:
In answer to the question, "How would you decide to create a class versus struct versus static class?", please see the microsoft documentation Choosing Between Class and Struct.
CompTIA Network+

Prepare for the CompTIA Network+ exam by learning how to troubleshoot, configure, and manage both wired and wireless networks.

Commented:
First, you want to find out about structs and classes (static classes are a kind of class).

So in .NET there are two basic categories for types; reference types and value types.

Reference types can be updated where ever they are called at; while value types can only be updated from the method in which they were defined; e.g. -
using System;

namespace EE_Q29137946
{
    class Program
    {
        static void Main(string[] args)
        {
            PersonStruct bob = new PersonStruct { Name = "Bob", Birthdate = new DateTime(1972, 3, 5) };
            PersonClass peter = new PersonClass { Name = "Peter", Birthdate = new DateTime(1974, 8, 20) };

            Console.WriteLine("Before age change");
            Console.WriteLine(bob.Age);
            Console.WriteLine(peter.Age);

            Console.WriteLine("Adding 5 years to Bob and Peter");
            ChangeBirthdate(bob);
            ChangeBirthdate(peter);

            Console.WriteLine("After age change");
            Console.WriteLine(bob.Age);
            Console.WriteLine(peter.Age);

            Console.ReadLine();
        }

        private static void ChangeBirthdate(IPerson person)
        {
            person.Birthdate = person.Birthdate.AddYears(-5);
        }
    }

    struct PersonStruct : IPerson
    {
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }
        public string Age { get { return $"Structure {Name} is {(DateTime.Now.Year - Birthdate.Year)} years old!!!"; } }
    }

    class PersonClass : IPerson
    {
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }
        public string Age { get { return $"Class {Name} is {(DateTime.Now.Year - Birthdate.Year)} years old!!!"; } }
    }

    interface IPerson
    {
        string Name { get; set; }
        DateTime Birthdate { get; set; }
        string Age { get; }
    }
}

Open in new window

Which produces the following output -Capture.PNGTo explain what you see here, both PersonStruct and PersonClass implement the IPerson interface.  This means that both can be passed to any method which accepts an IPerson interface as a parameter.  ChangeBirthdate is one such method.  When the bob instance of the PersonStruct is passed to the ChangeBirthdate method, only the instance inside of the method has it's birthdate changed, this is because it is a value type and by definition, the instance accessed within the ChangeBirthdate method is a copy of the instance passed to the method.  On the other hand, the peter instance of the PersonClass is updated because it is a reference type and so the instance that is passed to the method points to the same instance that it references.  We can prove this by printing out the values before leaving the ChangeBirthdate method; e.g. -
using System;

namespace EE_Q29137946
{
    class Program
    {
        static void Main(string[] args)
        {
            PersonStruct bob = new PersonStruct { Name = "Bob", Birthdate = new DateTime(1972, 3, 5) };
            PersonClass peter = new PersonClass { Name = "Peter", Birthdate = new DateTime(1974, 8, 20) };

            Console.WriteLine("Before age change");
            Console.WriteLine(bob.Age);
            Console.WriteLine(peter.Age);

            Console.WriteLine("Adding 5 years to Bob and Peter");
            ChangeBirthdate(bob);
            ChangeBirthdate(peter);

            Console.WriteLine("After age change");
            Console.WriteLine(bob.Age);
            Console.WriteLine(peter.Age);

            Console.ReadLine();
        }

        private static void ChangeBirthdate(IPerson person)
        {
            person.Birthdate = person.Birthdate.AddYears(-5);
            Console.WriteLine($"Inside ChangeBirthdate; We have changed the birthdate for {person.Name}; {person.Birthdate}");
            Console.WriteLine(person.Age);
            Console.WriteLine("Leaving the ChangeBirthdate Method");
        }
    }

    struct PersonStruct : IPerson
    {
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }
        public string Age { get { return $"Structure {Name} is {(DateTime.Now.Year - Birthdate.Year)} years old!!!"; } }
    }

    class PersonClass : IPerson
    {
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }
        public string Age { get { return $"Class {Name} is {(DateTime.Now.Year - Birthdate.Year)} years old!!!"; } }
    }

    interface IPerson
    {
        string Name { get; set; }
        DateTime Birthdate { get; set; }
        string Age { get; }
    }
}

Open in new window

Now produces the following output -Capture.PNG-saige-
Commented:
Now lets kick this up a notch, what are static classes?  Well static classes are classes which can be referenced without needing an instance.  So let's demonstrate that:
using System;

namespace EE_Q29137946
{
    class Program
    {
        static void Main(string[] args)
        {
            PersonStruct bob = new PersonStruct { Name = "Bob", Birthdate = new DateTime(1972, 3, 5) };
            PersonClass peter = new PersonClass { Name = "Peter", Birthdate = new DateTime(1974, 8, 20) };

            Console.WriteLine("Before age change");
            Console.WriteLine(bob.Age);
            Console.WriteLine(peter.Age);

            Console.WriteLine("Adding 5 years to Bob and Peter");
            Extensions.ChangeBirthdate(bob);
            Extensions.ChangeBirthdate(peter);

            Console.WriteLine("After age change");
            Console.WriteLine(bob.Age);
            Console.WriteLine(peter.Age);

            Console.ReadLine();
        }
    }

    struct PersonStruct : IPerson
    {
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }
        public string Age { get { return $"Structure {Name} is {(DateTime.Now.Year - Birthdate.Year)} years old!!!"; } }
    }

    class PersonClass : IPerson
    {
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }
        public string Age { get { return $"Class {Name} is {(DateTime.Now.Year - Birthdate.Year)} years old!!!"; } }
    }

    interface IPerson
    {
        string Name { get; set; }
        DateTime Birthdate { get; set; }
        string Age { get; }
    }

    static class Extensions
    {
        public static void ChangeBirthdate(this IPerson person)
        {
            person.Birthdate = person.Birthdate.AddYears(-5);
            Console.WriteLine($"Inside ChangeBirthdate; We have changed the birthdate for {person.Name}; {person.Birthdate}");
            Console.WriteLine(person.Age);
            Console.WriteLine("Leaving the ChangeBirthdate Method");
        }
    }
}

Open in new window

Which will produce the same output as my second example above.

-saige-
AndyAinscowFreelance programmer / Consultant

Commented:
>>How would you decide to create a class versus struct versus static class?

Might sound silly but I would read what each is with the pros and cons and specific details and then based on what I require the choice is obvious.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial