In this article, I am going to explain the following C# basics concepts.
- Value types & reference types
- Access Modifiers in C#
- Understanding Classes and other types
- class (Abstract, partial, sealed, static etc.)
- enum
- struct
- interface
- Understanding Partial Types and Partial Methods.
- use of ‘typeof’ keyword in C#.
- Calling multiple constructors of a class with single object creation.
- Understanding the output and behavior of C# basic code snippet.
- Implement and call the methods of the interfaces & the base class with the same name.
- Usage of ‘ref’ & ‘out’ keyword in C#.
- Using ‘params’ & ‘dynamic’ in method parameter.
I will be explaining all the topics, mentioned above in depth but the explanation will be more focused on the interview preparation i.e. I will explain all those things in the context of an interview. Actually, in the recent past, I have gone through dozens of interviews and I would like to share the experience with the other developers.
I am going to start with the very basic concepts and the purpose of this article is that the readers of this article can make themselves ready for C# interviews.
Value types & reference types
In C#, types have been divided into 2 parts, value types and the reference types. The value types directly store the data in the stack portion of RAM whereas the reference type stores reference of the data in the stack and save the actual data in heap but this is a half-truth statement. I will explain about it later to prove why it’s half-truth.
Value types
A value type contains its data directly and it is stored in the stack of memory. Examples of some built-in value types are Numeric types (sbyte, byte, short, int, long, float, double, decimal), char, bool, IntPtr, date, Struct and Enum is the value type.
If I need to create a new value type, then I can use structs to create a new value type. I can also use enum keyword to create a value type of enum type.
Reference types
Reference types store the address of their data i.e. pointer on the stack and actual data is stored in heap area of the memory. The heap memory is managed by the garbage collector.
As I said, the reference type does not store its data directly, so assigning a reference type value to another reference type variable creates a copy of the reference address (pointer) and assign it to the 2nd reference variable. Thus, now both the reference variables have the same address or pointer for which an actual data is stored in heap. If I make any change in one variable, then that value will also be reflected in another variable.
In some cases, it is not valid like when reallocating memory, it may update only one variable for which new memory allocation has been done.
Suppose you are passing an object of customer class, let's say “objCustomer” inside a method “Modify(…)” and then re-allocate the memory inside the “Modify(…)” method & provide its properties value. In that case, customer object “objCustomer” inside the “Modify(…)” will have different value and those change will not be available to the variable “objCustomer” accessed outside of “Modify(…)”.
You can also take the example of String class. ‘string’ is the best example for this scenario because in the case of a string, each time new memory is allocated.
I will explain about all those scenarios in depth in “Usage of ‘ref’ & ‘out’ keyword in C#” & “Understanding the behavior of ‘string’ in C#” section of this article.
Understanding Classes and other types
The table is given below to understand Classes and other types. If you are aware of all the behaviors of the classes and other types, then you can skip this section and move to next section. I will explain all those things one by one for the developers, who are not aware of it.
Note
You can see that static class can inherit a class. I have written no but used the * notation with that. It means a static class cannot inherit any other class but must inherit System.Object. Thus, we can also write the System.Object Class name in the inheritance list but there is no need to write the name System.Object explicitly because all the classes are being inherited from System.Object implicitly and we do not need to write it explicitly.
What are the different types of classes we can have?
We can have an abstract class, partial class, static class, sealed class, nested class & concrete class (simple class).
Static Class
static class Student {
public static int StudentId {
get;
set;
}
public static string StudentName {
get;
set;
}
}
Static Partial Class
public static partial class Student {
public static int StudentId {
get;
set;
} = 1;
public new static string ToString() {
return $ "Student Id is {StudentId:0000} and name is {StudentName}";
}
}
public static partial class Student {
public static string StudentName {
get;
set;
} = "Banketeshvar Narayan";
}
- I cannot create an instance of the static class.
- Static classes cannot have the instance constructors but it can have a static constructor.
The code snippet, mentioned below will give compile time error.
static class MyStaticClass {
MyStaticClass() {}
}
Error
CS0710 Static classes cannot have instance constructors
The code snippet, mentioned below will compile successfully.
static class MyStaticClass {
static MyStaticClass() {}
}
- Static classes cannot implement the interfaces.
The code snippet, mentioned below will give compile time error.
static class MyStaticClass: IInterface {
static MyStaticClass() {}
}
Error
CS0714 'MyStaticClass': static classes cannot implement interfaces
- A static class cannot derive from type. Static classes must derive from an object.
- A static class cannot be a base class.
The code snippet, mentioned below will give compile time error
static class MyStaticClass1 {
//your code
}
class MyClass2: MyStaticClass1 {
//your code
}
Error
CS0709 'MyClass2': cannot derive from static class 'MyStaticClass1'
Abstract Class
abstract class Student
{
public int StudentId {
get;
set;
}
public string StudentName {
get;
set;
}
public abstract void Add();
}
Abstract Partial Class
public abstract partial class Student {
public static int StudentId {
get;
set;
} = 1;
public override string ToString() {
return $ "Student Id is {StudentId:0000} and name is {StudentName}";
}
}
public abstract partial class Student {
public static string StudentName {
get;
set;
} = "Banketeshvar Narayan";
}
- It cannot create an instance of an abstract class i.e. abstract class cannot be instantiated.
The code snippet, mentioned below will give compile time error
abstract class MyClass {
//Your code
}
class Program {
static void Main(string[] args) {
MyClass obj = new MyClass();
}
}
Error
CS0144 Cannot create an instance of the abstract class or interface 'MyClass'
- An abstract class can have a non-static constructor and static constructor as well. It can implement an interface and can derive from another class. An abstract class can be a base class also. The sample code image of code snippet for the same is given below.
Sealed Class
sealed class Student {
public int StudentId {
get;
set;
} = 1;
public string StudentName {
get;
set;
} = "Banketeshvar Narayan";
public override string ToString() {
return $ "Student Id is {StudentId:0000} and name is {StudentName}";
}
}
Sealed Partial Class
public sealed partial class Student {
public static int StudentId {
get;
set;
} = 1;
public override string ToString() {
return $ "Student Id is {StudentId:0000} and name is {StudentName}";
}
}
public sealed partial class Student {
public static string StudentName {
get;
set;
} = "Banketeshvar Narayan";
}
Sealed class cannot be further inherited i.e. it cannot be a base class for any type but it can inherit a class and can be a child class. It can be instantiated, can have a static constructor, instance constructor and it can implement an interface also. It can be a partial class.
The pictorial representation of the statement is mentioned below.
If you would like to test the statement written in the pictorial representation, then you can use the code snippet, mentioned below.
namespace SealedClassExamples {
interface I { /* your Code */ }
public class Human { /*Your code */ }
public sealed class Student: Human, I {
static Student() { /*Your code */ }
public Student() { /*Your code */ }
}
class MyClass {
void DoSomething() {
Student st = new Student();
}
}
class A: Student {}
public sealed partial class Person {
public static string Name => "Banketeshvar Narayan";
}
}
Concrete Class (Simple Class)
class Student {
public int StudentId {
get;
set;
} = 1;
public string StudentName {
get;
set;
} = "Banketeshvar Narayan";
public override string ToString() {
return $ "Student Id is {StudentId:0000} and name is {StudentName}";
}
}
Partial Concrete Class
public partial class Student {
public int StudentId {
get;
set;
} = 1;
public override string ToString() {
return $ "Student Id is {StudentId:0000} and name is {StudentName}";
}
}
public partial class Student {
public string StudentName {
get;
set;
} = "Banketeshvar Narayan";
}
Concrete class or simple class is the class, which does not use any restriction like static, sealed or an abstract class.
Concrete classes can be a base class, child class, can be instantiated, can have a static constructor, can have instance constructor & can implement an interface.
Partial Method in C#
partial class Class1 {
partial void DoSomething();
}
partial class Class1 {
partial void DoSomething() {
WriteLine("Hello");
}
}
We can have partial method in C# but there are some restrictions
- Partial method must be declared already before implementing it.
If you are going to implement the partial method then defining declaration must be available for the same i.e. partial method must be declared already before implementing it.
i.e. the code mentioned below will give compile time error.
partial class Class1 {
//partial void DoSomething();
}
partial class Class1 {
partial void DoSomething() {
WriteLine("Hello");
}
}
Error CS0759
No defining declaration is found for implementing the declaration of the partial method 'Class1.DoSomething()'.
- Partial methods must have a void return type. The code mentioned below will give compile time error.
partial class Class1 {
partial int Add(int x, int y);
}
partial class Class1 {
partial int Add(int x, int y) {
return x + y;
}
}
- Accessibility of partial method is private and no access modifier is allowed.
partial class Class1 {
public partial void DoSomething();
/* Compile Time Error: Error
* CS0750 A partial method cannot have access modifiers
* or the virtual, abstract, override, new, sealed,
* or extern modifiers
*/
}
partial class Class1 {
partial void DoSomething() {
WriteLine("Hello");
}
}
- Signature of both the partial methods should be the same.
The code mentioned below will give compile time error because the signature does not match.
partial class Class1 {
partial void Add(int x, int y);
}
partial class Class1 {
partial void Add(int x, int y, int z) {
WriteLine($ "{x + y}");
}
/* Compilee Error: Error CS0759 No defining declaration found for
* implementing declaration of partial method 'Class1.Add(int, int, int)'
*/
}
- We can declare a partial method inside the partial class or inside the partial struct.
That is the type in which I am going to declare a partial method must be partial. The following type can be declared as partial.
- Partial Interface
- Partial Class
- Partial Structure
So, you can see that we can have partial interface, partial class & partial struct but the partial method can only be written inside Partial struct and Partial class.
Structure (struct) in C#
In C#, we can create a structure or struct, using the keyword struct. As explained earlier, a struct is a value type and it is directly stored in the stack of the memory.
Create a struct
using static System.Console;
namespace StructExample {
class Program {
static void Main(string[] args) {
MyCoordinates obj;
obj.xCoordinate = 30;
obj.yCoordinate = 40;
WriteLine($ "{obj.xCoordinate} {obj.yCoordinate}");
}
}
struct MyCoordinates {
public int xCoordinate;
public int yCoordinate;
}
}
Enum (enum) in C#
Enum is a value type in C# and the code snippet is mentioned below to explain how to create an enum.
enum RainbowColors {
RED = 1,
ORANGE = 2,
YELLOW = 3,
GREEN = 4,
BLUE = 5,
INDIGO = 6,
VIOLET = 7
}
Important Questions
- We can use foreach loop over the collection, which implements IEnumerable interface but enum does not implement any interface, can we use foreach loop with enum?
Answer
Yes, the complete code is mentioned below to demonstrate that how we can use foreach loop over enum
using System;
namespace EnumExample {
class Program {
static void Main(string[] args) {
foreach(var color in Enum.GetValues(typeof(RainbowColors))) {
Console.WriteLine(color);
}
}
}
enum RainbowColors {
RED = 1,
ORANGE = 2,
YELLOW = 3,
GREEN = 4,
BLUE = 5,
INDIGO = 6,
VIOLET = 7
}
}
- Can I write a partial enum?
Answer
No, if you will try to use the partial keyword with enum, then you will get a compiler error, as shown below.
Error
CS0267 “The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void'”
Interface
An interface can be created using the keyword ‘interface’ in C#. An interface is a contract and that’s why all the Methods, properties, Indexers, Events which are a part of the interface must be implemented by the class or struct, which implements the interface. An interface can contain only signature of Methods, Properties, Indexers and Events.
Following is an example of an Interface.
interface IInterface {
int MyProperty {
get;
set;
}
void Display();
}
Partial Interface
partial interface I1 {
void Method1();
void Method2();
}
- Can an interface implement another interface?
Answer
Yes, an Interface can implement another interface.
Example
interface I1 {
void Method1();
void Method2();
}
interface I2: I1 {
void Method3();
void Method4();
}
- Can an interface implement multiple interfaces?
Answer Yes, an interface can implement multiple interfaces.
Example
interface I1 {
void Method1();
void Method2();
}
interface I2: I1 {
void Method3();
void Method4();
}
interface I3: I1, I2 {
void Method5();
void Method6();
}
- Can an interface have events?
Answer
Yes, an Interface can have methods, properties, indexers & events.
- Can I use the public keyword with interface members?
Answer
No, all the members of the interface are public by default but we cannot use any access modifiers explicitly with the interface members.
- Can an interface have constructors?
Answer
No, Interfaces cannot contain constructors.
- Can I use the static keyword with the interface method?
Answer
No, we cannot use static and public modifiers with the interface method.
Access Modifiers in C#
What are the access modifiers allowed with Class?
Class
public & internal(default) only.
Class Members
We can use all the 5 access modifier i.e.private(default), protected, internal, protected internal and public.
public class User {}
Or
class User1 {}
Or
internal class User2 {}
Class Members with all the 5 access modifiers
public class User {
//private access modifiers
private int UserId {
get;
set;
} = 1;
//protected access modifiers
protected string UserName {
get;
set;
} = "Banketeshvar Narayan";
////internal access modifiers
internal string EmailId {
get;
set;
} = "[email protected]";
//protected internal access modifiers
protected internal string City {
get;
set;
} = "Delhi";
//public access modifiers
public string Country {
get;
set;
} = "India";
}
Note
The elements defined in a namespace cannot be explicitly declared as private, protected or protected internally.
What are the access modifiers allowed with enum?
Enum
default access modifier is internal and we can use public & internal explicitly.
Enum Fields
No access modifier is allowed with enum fields and default member accessibility is public.
enum IndianTricolor {
Saffron = 1,
White = 2,
Green = 3
}
internal enum IndianTricolor is shown below.
{
Saffron = 1,
White = 2,
Green = 3
}
Or
public enum IndianTricolor {
Saffron = 1,
White = 2,
Green = 3
}
What are the access modifiers allowed with an interface?
Interface
public & internal(default) only.
interface IUser1 {}
internal interface IUser1 {}
public interface IUser1 {}
Interface Members
No access modifier is allowed with the interface members and default member accessibility is public.
What are the access modifiers allowed with the struct?
Struct
public & internal (default) only.
Struct Members
Private, public and internal access modifiers are allowed with struct members and the default member accessibility is private.
public / internal(
default access modifier) struct MyStruct {
private(
default access modifier) / internal / protected int MyProperty {
get;
set;
}
}
Tips
Generally, most of the developers start remembering things rather than understanding the actual structure and behavior but it is not good for the developers.
If you look at the access modifier for the class, then you will notice that the default access modifier for the class is internal whereas default access modifier for a property is private, so I am going to give you four tips, which help you to understand allowed access modifiers and their behavior.
- The elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal. Thus, we can only use internal and public access modifiers with the class, interface, enum & struct.
- Class members can use all the 5 access modifiers where struct members cannot use access modifiers “protected” and “protected internal” because struct cannot be inherited.
- The default access modifier is "the most restricted access modifier you could declare for that member". Thus, default access for the class, interface, enum & struct is “internal” for enum & interface member default is public and for class and struct member; it’s private.
- If the members of a type can have only public accessibility, then we cannot use any access modifiers explicitly and it will always have public accessibility implicitly. Thus, interface and enum members cannot have access modifiers explicitly.
What is the use of ‘typeof’ keyword in C#?
It is used to get the types and using this, we can do a lot of things of reflection without using complex logic and a few examples are shown below.
Type t = typeof(User);
WriteLine(t.Assembly);
WriteLine(t.AssemblyQualifiedName);
WriteLine(t.IsAbstract);
WriteLine(t.IsSealed);
WriteLine(t.IsArray);
WriteLine(t.IsClass);
WriteLine(t.IsVisible);
WriteLine(t.IsValueType);
WriteLine(t.IsInterface);
How to Implement and call the same methods of interfaces and base class?
Condition 1
I have 2 interfaces, where both are having the same method and I would like to implement it the same class how it will be implemented
i.e. have the code, as shown below.
interface IInterface1 {
void Display();
}
interface IInterface2 {
void Display();
}
Now, I am going to implement it in the same class. Following is the code snippet.
class A: IInterface1, IInterface2 {
public void Display() {
WriteLine("Display method of class A");
}
}
//Then calling it using the below code
A objA = new A();
IInterface1 objB = new A();
IInterface2 objC = new A();
objA.Display();
objB.Display();
objC.Display();
Output
Display method of class A
Display method of class A
Display method of class A
In the code mentioned above, you can see that I have implemented only 1 Display() method. Thus, if we are going to use more than one interface and they are having the same method name then it is not necessary to implement all those methods explicitly but in this case, all the instances will point to the same method, as you can see in the example, mentioned above.
Condition 2
Now, I am going to Add 1 parameter to differentiate Interface methods.
interface IInterface1 {
void Display();
}
interface IInterface2 {
void Display(int x);
}
class A: IInterface1, IInterface2 {
public void Display() {
WriteLine("Display method of class A");
}
public void Display(int x) {
WriteLine($ "Display method {x:0000}");
}
}
class Program {
static void Main(string[] args) {
A objA = new A();
IInterface1 objB = new A();
IInterface2 objC = new A();
objA.Display();
objB.Display();
objC.Display(50);
}
}
Output
Display method of class A
Display method of class A
Display method 0050
Thus, you can see that still there is no issue and everything is working fine.
Condition 3
Now, let’s say Display() method in both the interfaces are having 0 parameters and I want to implement it separately, then I will implement it like the following code snippet.
class A: IInterface1, IInterface2 {
void IInterface1.Display() {
WriteLine("Display method of IInterface1");
}
void IInterface2.Display() {
WriteLine("Display method of IInterface2");
}
}
If you look at the code mentioned above, you will notice 2 things.
- I have used an interface name with the method name to implement it explicitly. This is known as “Implement Interface explicitly”.
- I have removed public access modifier because it will not allow any access modifiers. Do you know why it will not allow access modifier? Because now it is explicit implementation and behaving as an interface member.
Condition 4
What is the difference between the following 2 code snippets?
Code Snippet1
interface IInterface1 {
void Display();
}
class A: IInterface1 {
void IInterface1.Display() {
WriteLine("Display method of IInterface1");
}
}
Code Snippet2
interface IInterface1 {
void Display();
}
class A: IInterface1 {
public void Display() {
WriteLine("Display method of IInterface1");
}
}
You can see that in “Code Snippet 1”, I have implemented the interface method explicitly, whereas in “Code Snippet 2” an interface method has been implemented implicitly.
You can call the implicitly implemented method of an interface by creating an object of the class, which implements it without the interface reference.
i.e. the code snippet, mentioned below will be compiled and will give the same output while being called by objA or objB.
interface IInterface1 {
void Display();
}
class A: IInterface1 {
public void Display() {
WriteLine("Display method of IInterface1");
}
}
A objA = new A();
IInterface1 objB = new A();
objA.Display();
objB.Display();
The code snippet, mentioned below will not be compiled.
interface IInterface1 {
void Display();
}
class A: IInterface1 {
void IInterface1.Display() {
WriteLine("Display method of IInterface1");
}
}
A objA = new A();
IInterface1 objB = new A();
objA.Display();
objB.Display();
Error
'A' does not contain a definition for 'Display' and no extension method 'Display' accepts a first argument of type 'A' could be found (are you missing a using directive or an assembly reference?)
You may be wondering why it is giving the compile time error. The reason for compile time error is the Display() method is having implementation inside class A but it is explicitly mentioned that it is only member of “IInterface1”.
Now I am going put one more condition in front of you and let’s try to understand the code snippet, mentioned below.
Condition 5
A class is having a base class and is also implementing two other interfaces and the types, which have the same method name.
interface IInterface1 {
void Display();
}
interface IInterface2 {
void Display();
}
class B {
public void Display() {
WriteLine("Display method of class B");
}
}
A objA = new A();
IInterface1 objB = new A();
IInterface2 objC = new A();
objA.Display();
objB.Display();
objC.Display();
Output
Display method of class B
Display method of IInterface1
Display method of IInterface2
Condition 6
class A: B, IInterface1, IInterface2 {
public void Display() {
WriteLine("Display method written inside A");
}
}
A objA = new A();
objA.Display();
It will call method of Class A and will not call its parent class method.
If you want to call parent class method, then you have to give reference to the parent class method.
i.e.
B objD = new B(); objD.Display();
After going through all these 6 different conditions, I hope that if an interviewer is trying to complicate the situation of implicit and explicit method implementation to any level, you will not be confused and you will be able to answer it confidently.
How to call multiple constructors of a class with single object creation?
In the example mentioned below, I have a class “A”, which is having 4 instance constructors. The first constructor is a Parameterless constructor and the second constructor is having one parameter, the third constructor is having two parameters and the fourth constructor is having three parameters.
class A {
public A() {
WriteLine("Parameterless constructor called");
}
public A(int x) {
WriteLine("constructor with 1 parameter called");
}
public A(int x, int y) {
WriteLine("constructor with 2 parameters called");
}
public A(int x, int y, int z) {
WriteLine("constructor with 3 parameters called");
}
}
Now, I would like to call all those 4 constructors by just creating only one object. Let’s see, how can it be done? The new code will be, as shown below.
class A {
public A(): this(0) {
WriteLine("Parameterless constructor called");
}
public A(int x): this(x, 0) {
WriteLine("constructor with 1 parameter called");
}
public A(int x, int y): this(x, y, 0) {
WriteLine("constructor with 2 parameters called");
}
public A(int x, int y, int z) {
WriteLine("constructor with 3 parameters called");
}
}
A a = new A(); //or // A a = new A { };
And output will be
constructor with 3 parameters called
constructor with 2 parameters called
constructor with 1 parameter called
Parameterless constructor called
I am going to ask you few questions of C# code snippet output, which are very popular and can be asked to anyone. So, let’s continue with the code snippets, mentioned below.
What will be the output of below code Snippet?
using static System.Console;
namespace Example1 {
class A {
public void Display() {
WriteLine($ "Class A");
}
}
class B: A {
public void Display() {
WriteLine($ "Class B");
}
}
class Program {
static void Main(string[] args) {
A obj1 = new A();
A obj2 = new B();
B obj3 = new B();
obj1.Display();
obj2.Display();
obj3.Display();
}
}
}
Output
Class A
Class A
Class B
What will be the output of the code snippet, mentioned below, if I create different types of objects in different ways?
class A {
public void Display() {
WriteLine($ "Class A");
}
}
class B: A {
public void Display() {
WriteLine($ "Class B");
}
}
class C: A {
public static void Display() {
WriteLine($ "Class C");
}
}
class D: A {
public virtual void Display() {
WriteLine($ "Class D");
}
}
class E: A {
public virtual new void Display() {
WriteLine($ "Class E");
}
}
abstract class F: A {
public abstract void Display();
}
abstract class G: A {
public abstract new void Display();
}
abstract class H: A {
public abstract void Display(int x);
}
I am not going to write the output of the code snippet, mentioned above rather I am leaving this as an exercise for the developers whose OOPS is not strong, so they can execute all the scenarios, mentioned above with the different combinations and can understand basics of OOPS. If anybody thinks that he needs an output of the code snippet, mentioned below then I will put it in the comment section of this article later on. I am also going to give some tips specifically compiler error messages for the preceding code snippet so that you can understand it in a better way.
Tips (compiler error messages)
- A static member cannot be marked as an override, virtual or abstract.
- It cannot be declared as the instance members in a static class.
- An object reference is required for the non-static field, method or property.
- An abstract class cannot be sealed or static. A class cannot be both static and sealed.
- The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface' or 'void'.
- Elements defined in a namespace cannot be explicitly declared as private, protected or protected internally.
What is the use of 'extern' keyword in C#?
We use 'extern' keyword with a method to indicate that the method has been implemented externally i.e. out of your current C# code. Below is a code sample from MSDN, which describes the use of extern
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
NOTE
While using [DllImport("User32.dll")], you need to include the namespace System.Runtime.InteropServices;
for complete details about extern visit here.
Sequence of Modifiers and other attributes with class and method
In the case of C# sometimes sequence of modifiers matters and you should be aware of that if you are going for an interview.
e.g. public abstract partial class Student or public partial abstract class Student
You would be wondering why I am explaining microlevel questions? I am explaining it because in some cases, you have to face such questions and you will feel a bit irritated or upset if you are not aware of all those things.
Sometimes sequence matters and sometimes it doesn’t matter but we should keep some best practices in mind so that we write an error free code.
Class
[modifiers] [partial] className [:] [inheritance list]
Method
[modifiers] [partial] returnType methodName([parameters])
Method Modifiers List.
- new
- internal
- private
- protected
- public
- abstract
- async
- extern
- override
- sealed
- static
- virtual
There are some more modifiers, which I have not mentioned here because they are used rarely.
Usage of ref keyword in C#
When we pass a value type variable as a parameter, then it passes its value as a parameter i.e. making a copy of the data. Making any changes inside the method in which it has been passed as a parameter will not affect the variable accessed outside the method. Because it is passed as a value and whatever the changes will be made inside the local method will be done on a copy of that variable.
If we need to change the value type variable from inside the method in which it has been passed as a parameter, then you can pass this value type variable as the reference, using the ‘ref’ keyword. In this case, the reference of value type will be passed as a parameter rather than the value of the variable.
Let’s consider about the reference type
A variable of the reference type contains the reference to its data and does not contain data directly. Whenever we pass a reference type variable as a parameter, then the data is not passed but the reference of the variable is passed inside the method i.e. passes the value of memory address not the value of data and that’s why, if I make any change to this variable inside the method, then it will be available outside the method but it is only limited to the modification and if I am going to allocate a new memory and modifying the variable, then these changes will not be reflected outside the method.
If I need that the changes be done inside the method for the variable by allocating new memory it should be reflected outside the method in that case, we need to pass the parameter of reference type with ‘ref’ keyword. If I pass a reference type variable parameter using ‘ref’ keyword, then the reference of the memory address is itself passed as reference and so allocating a new memory will also be available outside the method.
Below is the pictorial representation of the same thing stated above.
There are four combinations of passing the parameter inside a method. There are a lot of other options to pass a parameter as value but I am not going to discuss it here otherwise it will create confusion. I will discuss other parameter passing options in a separate section.
- Passing Value type variable without ‘ref’ keyword.
- Passing Value type variable with ‘ref’ keyword.
- Passing reference type variable without ‘ref’ keyword.
- Passing reference type variable with ‘ref’ keyword.
Passing Value type variable without ‘ref’ keyword
In the case mentioned above, the variable x is having an initial value 20 and its value i.e. 20 is passed as a parameter for the method Modify. Inside the method modify it has been modified and added 50 to its previous value so it becomes 70 but the value of the variable ‘x’ outside the Modify() method is still 20 because it has modified its value not the reference.
Below is the complete code
using static System.Console;
namespace PassingValueTypeWithoutRef {
class Program {
static void Main(string[] args) {
Program p = new Program();
int x = 20;
p.Modify(x);
WriteLine(x);
}
public void Modify(int x) {
x += 50;
WriteLine(x);
}
}
}
Passing Value type variable with ‘ref’ keyword
In the case mentioned above, the variable x is having an initial value 20 and its reference passed as a parameter for the method Modify. Inside the method modify it has been modified and added 50 to its previous value so it becomes 70. As this variable has been passed as reference i.e. value of its address has been passed instead of data so the value of the variable ‘x’ outside the Modify method is also updated and you will get 70 everywhere.
Below is the complete code
using static System.Console;
namespace PassingValueTypeWithRef {
class Program {
static void Main(string[] args) {
Program p = new Program();
int x = 20;
p.Modify(x);
WriteLine(x);
}
public void Modify(int x) {
x += 50;
WriteLine(x);
}
}
}
Passing reference type variable without ‘ref’ keyword
In C#, whatever we passed inside the method as a parameter is always passed as the value. So, that happens when we pass value type then copy of a value typed is passed, whereas in the case of reference type variable its reference address is passed as a method parameter.
In the example mentioned above, you can see that when I am passing a reference type as a parameter then its address is being passed as data not the actual data. Due to this, if I change the user object from the ModifyUser() method, then it is being reflected outside but If I allocate a new memory and then make any change; it will not be reflected outside the method.
Complete Code
using static System.Console;
namespace PassingReferenceTypeWithoutRef {
class Program {
static void Main(string[] args) {
User user = new User {
UserId = 101
};
ModifyUser(user);
WriteLine($ "User id: {user.UserId} & user name: {user.UserName}");
}
public static void ModifyUser(User user) {
user.UserName = "Banketeshvar Narayan";
user = new User {
UserId = 102,
UserName = "Manish Sharma"
};
WriteLine($ "User id: {user.UserId} & user name: {user.UserName}");
}
}
class User {
public int UserId {
get;
set;
}
public string UserName {
get;
set;
}
}
}
Passing reference type variable with ‘ref’ keyword
In the example mentioned above, you can see that when I am passing a reference type as a parameter, then its address is being passed as the data and not the actual data. Due to this, if I change the user object from the ModifyUser() method, then it is being reflected outside, even if I allocate a new memory and then make any change; it will be reflected outside the method.
Complete Code
using static System.Console;
namespace PassingReferenceTypeWithRef {
class Program {
static void Main(string[] args) {
User user = new User {
UserId = 101
};
ModifyUser(ref user);
WriteLine($ "User id: {user.UserId} & user name: {user.UserName}");
}
public static void ModifyUser(ref User user) {
user.UserName = "Banketeshvar Narayan";
user = new User {
UserId = 102,
UserName = "Manish Sharma"
};
WriteLine($ "User id: {user.UserId} & user name: {user.UserName}");
}
}
class User {
public int UserId {
get;
set;
}
public string UserName {
get;
set;
}
}
}
Passing string variable without ‘ref’ keyword
The String is the reference type but sometimes it behaves like the value type. Even though in the current scenario, if I pass the string inside a method and modify it, then it will not be affected to the outside variable from where the method has been called. For the code snippet mentioned below, an output will not be the same.
class Program {
static void Main(string[] args) {
string name = "B Narayan";
ModifyName(name);
WriteLine($ "name is : {name}");
//output: name is : B Narayan
}
public static void ModifyName(string name) {
name = "Manish Sharma";
WriteLine($ "name is : {name}");
//output: name is : Manish Sharma
}
}
As you can see the string modified inside the method is not affecting the outside variable, so if we need to modify outer variable from ModifyName() method, then we have to pass the string parameter with ref keyword.
Passing string variable with ‘ref’ keyword
class Program {
static void Main(string[] args) {
string name = "B Narayan";
ModifyName(ref name);
WriteLine($ "name is : {name}");
//output: name is : Manish Sharma
}
public static void ModifyName(ref string name) {
name = "Manish Sharma";
WriteLine($ "name is : {name}");
//output: name is : Manish Sharma
}
}
Now, you can see that I have passed the string variable name with ref keyword, so it has been modified on both the places.
Usage of ‘out’ keyword in C#
We can use ‘out’ keyword with the parameter and it behaves very similar to the parameter passed with ‘ref’ keyword but any argument passed as out parameter need not be initialized whereas in the case of 'ref', it must be initialized. Another difference is that ref parameter may be assigned inside the method in which it is called (not necessary), but in the case of “out” it must be assigned in the calling method before any exit.
Using ‘params’ in method parameter
The ‘params’ keyword can be used to specify a method parameter that takes a variable number of arguments. When we use ‘params’ keyword to pass the variable number of arguments, we can send any number of arguments or no arguments but all the arguments passed should be of the same type.
A method can have the only parameter with ‘params’ keyword or with additional parameters and ‘params’ as last parameters but no other parameters can be passed after ‘params’. Let’s try to understand with some examples.
Example 1
static void Main(string[] args) {
string my1stLine = "This is my first Line";
string my2ndLine = "This is my second Line";
string my3rdline = "This is my Third Line";
string my4thline = "This is my fourth Line";
Print(my1stLine, my2ndLine, my3rdline, my4thline);
}
public static void Print(params string[] listToPrint) {
foreach(var item in listToPrint) {
WriteLine(item);
}
}
Example 2
static void Main(string[] args) {
int userId = 1001;
string email1 = "[email protected]";
string email2 = "[email protected]";
string email3 = "[email protected]";
string email4 = "[email protected]";
UserDetails(userId, email1, email2, email3, email4);
}
public static void UserDetails(int UseId, params string[] emailIds) {
foreach(var email in emailIds) {
WriteLine($ "userId is {UseId} and emailId is {email}");
}
}
Example 3
public static void UserDetails(params string[] emailIds, int UseId) {
foreach(var email in emailIds) {
WriteLine($ "userId is {UseId} and emailId is {email}");
}
}
Out of the three examples, mentioned above- Example1 & Example 2 will compile & run successfully but the third example will not be compiled. It will give the errors, as shown below.
Error
A params parameter must be the last parameter in a formal parameter list
So far, I have discussed a lot about the method and I would like to mention one last thing, where we can also pass dynamic parameters in the method.
class Program {
static void MyDynamicMethod(dynamic dynamicparam) {
dynamicparam.DoSomethingDynamic(); // Called dynamically
}
static void Main(string[] args) {
MyDynamicMethod("dynamicValue");
}
}
This article has become very long already, so I am not going to tell you more about dynamic types but hopefully in the next article of this series, I will discuss it in more depth.
For C# basics concepts, you can refer to the articles written by me. Following is the list for the same.
More Interview Questions