C# Interview Questions and Answers - Part 01
Introduction
C# Interview Questions and Answers - Part 01
There are four pillars of any object-oriented programming language:
Abstraction is the process of hiding the internal complex details and showing only the minimum required functionality to the external users. Both abstract class and interface are used for data abstraction. It ensures that only the required information is visible to the user and the rest of the information is hidden from the external world.
Please read the abstract class article here, C#8 interface here, an abstract class vs interface here for more details.
Encapsulation is the process of binding the data members (properties or variables) to the methods. It wraps the member functions and data members into a single unit. The encapsulation hides or restricts the internal data member from accessing the other external classes. Therefore it is also known as data hiding.
Encapsulation is achieved by declaring all the variables in the class as private and using properties in the class to set and get the values of variables. Please watch the variable vs properties video here for more details.
Inheritance is a way to access and use the properties and methods of other classes. The original class is known as the base class and the class which inherits the functionality of the base class is the derived class. Inheritance provides code reusability. C# does not support multiple class inheritance due to the diamond problem but multiple interfaces inheritance is allowed.
Please read the Multiple Interface Inheritance and Diamond Problem Resolution in C#8 here for more details.
The term "polymorphism" means "having many forms". So in OOPS, it means that an object can have multiple functionalities. There are two types of polymorphism in OOPS.
Static Polymorphism or Early Binding involves linking a method with an object during compile time, hence also known as Compile Time Binding. Method Overloading and Operator Overloading are the way to achieve Static Polymorphism. Please read the Static Polymorphism article here for more details
Dynamic Polymorphism or Late Binding involves linking a method with an object during run time, hence also known as Run Time-Binding. Method Overriding is a way to achieve Dynamic Polymorphism. Please read the Dynamic Polymorphism article here for more details.
Abstraction is a way to only show the essential data to the user. It solves an issue at the design level. For abstraction, abstract classes and interfaces are used.
On the other hand, encapsulation hides the code and data into a single entity or unit so that the data can be protected from the outside world. It is an implementation-level process. It is achieved by different access modifiers like private, public, protected. The getters and setters methods of properties are used to hide the data.
- All the structs are value types while classes are reference types.
- Structs cannot have destructors, but classes can have destructors.
- Structs cannot have an explicit default constructor while a class can have a default constructor.
- Structs do not support inheritance while classes support inheritance.
- Instance field declarations for a struct are not permitted to include variable initializers while a class can initialize the field members.
- In C# user can copy one structure object into another one using the assignment operator (=) but a class cannot be.
- A structure cannot have the abstract, virtual, or sealed members while a class can have.
- A structure cannot have a sealed method but a class can have sealed methods.
- A structure can only override the Object class virtual methods while a class can override any base class virtual method and abstract method.
Please read the complete C# Structure article here.
- All the Classes, records, and structs declared directly within a namespace(non-nested) can be either public or internal. The internal is the default if no access modifier is specified.
- Class and struct members, including nested classes and structs, have private access by default.
- All private nested types aren't accessible from outside the containing type.
- Derived classes can't have greater accessibility than their base types. So you can't declare a public class B that derives from an internal class A.
- Struct members can't be declared as protected, protected internal, or private protected because structs don't support inheritance.
- Normally, the accessibility of a member isn't greater than the accessibility of the type that contains it. However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or override virtual methods that are defined in a public base class.
- User-defined operators must always be declared as public and static.
- Destructors can't have any accessibility modifiers.
- The type of any member field, property, or event must be at least as accessible as the member itself. Similarly, the return type and the parameter types of any method, indexer, or delegate must be at least as accessible as the member itself.
- Interfaces declared directly within a namespace can be public or internal and, just like classes and structs, interfaces default to internal access.
- Interface members are public by default because the purpose of an interface is to enable other types to access a class or struct. Interface member declarations may also include any access modifier after C#8.
- Enumeration members are always public, and no access modifiers can be applied.
- Since delegates behave like classes and structs. So by default, they have internal access when declared directly within a namespace, and private access when nested.
- Method Overloading
- Operator Overloading
- Constructor Overloading
- Indexer Overloading
- An abstract method cannot contain body definition while a virtual method must have a body definition.
- Overriding all the abstract methods in the inheriting concrete class is mandatory while overriding the virtual methods is optional.
- The "abstract" modifier can be used while overriding the abstract method but the "virtual" modifier cannot be used while overriding a virtual method.
- An abstract method can only be declared in an abstract class while a virtual method can be defined in a non-abstract class as well.
- A virtual method can be overridden to abstract for achieving re-abstraction but an abstract method cannot be overridden to virtual.
- Method Overloading is static polymorphism while Method Overriding is dynamic polymorphism. So Method Overloading executes at compile-time while Method Overriding executes at run-time.
- Method Overloading is generally defined in the same class while Method Overriding only is used in inheritance.
- For Method Overriding the base class method must be virtual (abstract in abstract class) while it is not required in the case of Method Overloading.
- In Method Overriding you can not change the method signature in the derived class while Method Overloading is only possible with different method signatures.
- Method Overriding requires forcefully rewriting the method definition with the same signature in the derived class while Method Overloading is more flexible by allowing different signatures for different overloading methods.
- The Overriding Method is not considered as an overloaded member of the derived class, while other methods with the same name and different signatures are considered as the overloaded methods.