Program to check if a string is a Palindrome?
class Program
{
static void Main(string[] args)
{
string originalString, reverseString = "";
Console.WriteLine("Enter string to Check Palindrome: ");
originalString = Console.ReadLine();
for (int i = originalString.Length - 1; i >= 0; i--)
{
reverseString = reverseString + originalString[i].ToString();
}
if (reverseString == originalString)
{
Console.WriteLine("String is Palindrome \n Entered String Was {0} and reverse string is {1}", originalString, reverseString);
}
else
{
Console.WriteLine("String is not Palindrome \n Entered String Was {0} and reverse string is {1}", originalString, reverseString);
}
Console.ReadLine();
}
}
Program to perform bubble sort.
class Program
{
static void Main(string[] args)
{
int[] number = { 89, 1, 45, 92, 167, 12, 99 };
bool flag = true;
int temp;
int numLength = number.Length;
//sorting an array
for (int i = 1; (i <= (numLength - 1)) && flag==true; i++)
{
flag = false;
for (int j = 0; j < (numLength - 1); j++)
{
if (number[j + 1] > number[j])
{
temp = number[j];
number[j] = number[j + 1];
number[j + 1] = temp;
flag = true;
}
}
}
//Sorted array
//foreach (int num in number)
//{
// Console.Write("\t {0}", num);
//}
//Print in descending order
for (int i = 0;i< number.Length;i++)
{
Console.Write("\t {0}", number[i]);
}
Console.WriteLine("\n");
//Print in ascending order
for (int i = number.Length - 1; i >= 0; i--)
{
Console.Write("\t {0}", number[i]);
}
Console.ReadLine();
}
}
Write code to split a string without using split function.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a sting to Split its words :");
string str = Console.ReadLine();
ArrayList ar = new ArrayList();
string tmp = "";
for (int i = 0; i < str.Length; i++)
{
if (str[i] != ' ')
{
tmp = tmp + str[i];
continue;
}
ar.Add(tmp);
tmp = "";
}
foreach (string a in ar)
{
Console.WriteLine(a);
}
Console.ReadLine();
}
}
Write code to print the words in reverse in the given string without using any inbuilt functions. Not the entire string, only words in the given string should reverse.
class Program
{
static void Main(string[] args)
{
int temp;
Console.WriteLine("Enter a sting to reversed its words :");
string orginalString = Console.ReadLine();
string[] reverseString = orginalString.Split(' ');
int stingLength = reverseString.Length - 1;
temp = stingLength;
for (int i = stingLength; temp >= 0; stingLength--)
{
Console.Write(reverseString[temp] + "" + ' ');
--temp;
}
Console.ReadLine();
}
}
Given an unsorted array which has a number in the majority (a number appears more than 50% in the array), find that number?
class Program
{
static void findMajority(int[] arr, int n)
{
int maxCount = 0;
int index = -1;
for (int i = 0; i < n; i++)
{
int count = 0;
for (int j = 0; j < n; j++)
{
if (arr[i] == arr[j])
count++;
}
if (count > maxCount)
{
maxCount = count;
index = i;
}
}
if (maxCount > n / 2)
{
Console.WriteLine("The number appears more than 50% in the array is =" + arr[index]);
Console.WriteLine("And its Count =" + maxCount);
}
else
{
Console.WriteLine("No Majority Element");
}
}
static void Main(string[] args)
{
int[] arr = { 1, 1, 2, 1, 3, 5, 1 };
int arrayLength = arr.Length;
// Function calling
findMajority(arr, arrayLength);
Console.ReadLine();
}
}
Write a Program which checks if two Strings are Anagram or not?
Two words are said to be Anagrams of each other if they share the same set of letters to form the respective words. Remember, it’s just rearranging the existing letter set. For example, Silent and Listen.
The following example is not an Anagram since we use one “I” in DIANA and two “a”s whereas INDIA has two “I”s and one “a”.
The following example is not an Anagram since we use one “I” in DIANA and two “a”s whereas INDIA has two “I”s and one “a”.
class Program
{
static void Main(string[] args)
{
Console.Write("Enter first word:");
string word1 = Console.ReadLine();
Console.Write("Enter second word:");
string word2 = Console.ReadLine();
//step 1
char[] char1 = word1.ToLower().ToCharArray();
char[] char2 = word2.ToLower().ToCharArray();
//Step 2
Array.Sort(char1);
Array.Sort(char2);
//Step 3
string NewWord1 = new string(char1);
string NewWord2 = new string(char2);
//Step 4
//ToLower allows to compare the words in same case, in this case, lower case.
//ToUpper will also do exact same thing in this context
if (NewWord1 == NewWord2)
{
Console.WriteLine("Yes! Words \"{0}\" and \"{1}\" are Anagrams", word1, word2);
}
else
{
Console.WriteLine("No! Words \"{0}\" and \"{1}\" are not Anagrams", word1, word2);
}
Console.ReadLine();
}
}
How to find all pairs of elements in an integer array, whose sum is equal to a given number?
class Program
{
static bool hasArrayTwoCandidates(int[] A,
int arr_size, int sum)
{
int l, r;
/* Sort the elements */
sort(A, 0, arr_size - 1);
/* Now look for the two candidates
in the sorted array*/
l = 0;
r = arr_size - 1;
while (l < r)
{
if (A[l] + A[r] == sum)
return true;
else if (A[l] + A[r] < sum)
l++;
else // A[i] + A[j] > sum
r--;
}
return false;
}
/* Below functions are only to sort the
array using QuickSort */
/* This function takes last element as pivot,
places the pivot element at its correct
position in sorted array, and places all
smaller (smaller than pivot) to left of
pivot and all greater elements to right
of pivot */
static int partition(int[] arr, int low, int high)
{
int pivot = arr[high];
// index of smaller element
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
// If current element is smaller
// than or equal to pivot
if (arr[j] <= pivot)
{
i++;
// swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// swap arr[i+1] and arr[high] (or pivot)
int temp1 = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp1;
return i + 1;
}
/* The main function that
implements QuickSort()
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
static void sort(int[] arr, int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[pi]
is now at right place */
int pi = partition(arr, low, high);
// Recursively sort elements before
// partition and after partition
sort(arr, low, pi - 1);
sort(arr, pi + 1, high);
}
}
static void Main(string[] args)
{
int[] A = { 1, 4, 45, 6, 10, -8 };
int n = 16;
int arr_size = 6;
if (hasArrayTwoCandidates(A, arr_size, n))
Console.Write("Array has two elements" +
" with given sum");
else
Console.Write("Array doesn't have " +
"two elements with given sum");
Console.ReadLine();
}
}
Or
class Program
{
static void printpairs(int[] arr,int sum)
{
HashSet<int> s = new HashSet<int>();
for (int i = 0; i < arr.Length; ++i)
{
int temp = sum - arr[i];
// checking for condition
if (temp >= 0 && s.Contains(temp))
{
Console.Write("Pair with given sum " +
sum + " is (" + arr[i] +
", " + temp + ")");
}
s.Add(arr[i]);
}
}
static void Main(string[] args)
{
int[] A = new int[]{1, 4, 45, 6, 10, 8};
int n = 16;
printpairs(A, n);
Console.ReadLine();
}
}
Write a function to remove duplicate characters from String?
static string RemoveDuplicateChars(string key)
{
string result = "";
foreach (char value in key)
{
if (result.IndexOf(value) == -1)
{
result += value;
}
}
return result;
}
static void Main(string[] args)
{
Console.WriteLine("Enter a string to remove duplicate characters:");
string str=Console.ReadLine();
string dupChar = RemoveDuplicateChars(str);
Console.WriteLine("After removing duplicate character the string is :-"+dupChar);
Console.ReadLine();
}
What is the difference between constants and read-only?
The constant modifier is used to declare local variables that given initial values when they are declared. But constant variables cannot be initialized using a constructor like read only variables.
Ex: - const int i=10;
A read-only field can be given a value when it is declared or by assigning a value within a constructor. Once the value has been set, it cannot be changed outside the constructor.
Thus, a read only field is good way to create a fixed value that has its value set by a constructor. Both static and non-static read-only fields are allowed
Ex:-
Class My Class
{
Public static read only int size=10;
}
Static void Main()
{
Int [] source = new int [myclas.size];
Myclass.size=100; //Error
}
What is value type and reference type?
Value type stores the data on stack which is a place where data stores in fixed length such as int, float, char etc. Stack is a data structure that works on a principle FILO or LIFO and this stack works under the control of OS, maintain a separate stack for each programmatically exception. When the execution of a program starts the OS creates a stack for the program for storing the variable and this stack gets cleared at the end of program execution. It is capable of allocation the memory in fixed size that can’t be changed after allocation and moreover it is faster in access.
Reference type stored on heap memory which is the other place where data can stored. C# supports two predefined reference types string and object. In .Net the heap is under the control of Garbage Collector providing automatic memory management.
What is boxing an Unboxing?
If a value type is stored in a reference type variable we called it as boxing.
Ex: - int x=100;
Object obj=x; //boxing
If a reference type which contains value type in it and if converted back into a value type we called it as Unboxing.
Ex: - int y=convert.Tointe32 (obj); //Unboxing
All C# value types are derived from object. When an object reference refers to a value type, a process known as boxing occurs. Boxing causes the values of a value type to be stored in an object instance. Thus, a value type is “boxed” inside an object. This object can then be used like any other object.
Unboxing is the process of retrieving a value from a boxed object. This action is performed using an explicit cast from the object reference to its corresponding value type.
What is dynamic data type?
Starting with .Net 4.0, C# supports dynamic type. Variables typed as dynamic are used in a late-bound fashion, meaning that operations applied to them are resolved at runtime rather than at compile time. This is useful when dealing with an object that cannot be typed statically in a comfortable manner. Samples include XML documents without an XSD schema or objects from dynamic languages such as Python, Ruby, or JavaScript.
Ex:-
Object o=Get Something();
o.DoSomething(); //compile time error; system. Object does not have Do Something
Dynamic d=Get Something ();
d.DoSomething (); //check for the presence of Do Something at runtime
What are implicitly typed variables?
In C# variables must be declared. Normally, a declaration includes the type of the variables, such as int or bool, followed by the name of the variable. However, beginning with C# 3.0, it became possible to let the compiler determine the type of a local variable based on the value used to initialize it. This is called an implicitly typed variable.
An implicitly types variable is declared using the keyword var, and it must be initialized. The compiler uses the type of the initialize to determine the type of the variable. Here is an example:
Var e= .7183;
Now e is of type float datatype.
What is Static class?
There will be times when you want to define a class member that will be used independently i.e. not using the any object of that class. Normally, a class member must be accessed through an object of its class, but it is possible to create a member that can be used by itself, without reference to a specific instance. To create such a member, precede its declaration with the keyword static.
When a member is declared static, it can be accessed before any objects of its class are created and without reference to any object. You can declare both methods and variables to be static. The most common example of a static member is Main( ), which is declared static because it must be called by the operating system when your program starts execution.
Outside the class, to refer a static member, you must specify the name of its class, followed by the dot operator. No object needs to be created. In fact, a static member cannot be accessed through an object instance. It must be accessed through its class name. For example, assume a static variable called count that is a member of a class called Timer. To assign count the value 10, use this line:
Timer.count = 10;
This format is similar to that used to access normal instance variables through an object, except that the class name is used. A static method can be called in the same way—by use of the dot operator along with the class name.
Variables declared as static are, essentially, global variables. When objects of its class are declared, no copy of a static variable is made. Instead, all instances of the class share the same static variable. A static variable is initialized before its class is used. If no explicit initializer is specified, it is initialized to zero for numeric types, null in the case of reference types, or false for variables of type bool. Thus, a static variable always has a value.
The difference between a static method and a normal method is that the static method can be called through its class name, without any instance of that class being created.
A static method does not have a this reference. This is because a static method does not execute relative to any object.
A static method can directly call only other static methods of its class. It cannot directly call an instance method of its class. The reason is that instance methods operate on specific objects, but a static method is not called on an object. Thus, on what object would the instance method operate?
A similar restriction applies to static data. A static method can directly access only other static data of its class. It cannot operate on an instance variable of its class because there is no object to operate on.
A static class has two important features. First, no object of a static class can be created. Second, a static class must contain only static members. A primary use of a static class is found when working with extension methods,
What is static constructor?
A static constructor is called automatically when the class is first loaded, before any objects are created and before any instance constructors are called. Thus, the primary use for a static constructor is to initialize features that apply to the class as a whole, rather than to an instance of the class. A static constructor cannot have access modifiers and cannot be called directly by your program.
What is an extension method?
Extension methods provide a means by which functionality can be added to a class without using the normal inheritance mechanism. Although you won’t often create your own extension methods (because the inheritance mechanism offers a better solution in many cases), it is still important that you understand how they work because of their integral importance to LINQ.
An extension method is a static method that must be contained within a static, non-generic class. The type of its first parameter determines the type of objects on which the extension method can be called. Furthermore, the first parameter must be modified by this. The object on which the method is invoked is passed automatically to the first parameter. It is not explicitly passed in the argument list. A key point is that even though an extension method is declared static, it can still be called on an object, just as if it were an instance method.
Here is the general form of an extension method:
static ret-type name(this invoked-on-type ob, param-list)
Of course, if there are no arguments other than the one passed implicitly to ob, then param-list will be empty. Remember, the first parameter is automatically passed the object on which the method is invoked. In general, an extension method will be a public member of its class. Here is an example that creates three simple extension methods:
static class MyExtMeths
{
// Return the reciprocal of a double.
public static double Reciprocal(this double v)
{
return 1.0 / v;
}
// Reverse the case of letters within a string and
// return the result.
public static string RevCase(this string str)
{
string temp = "";
foreach (char ch in str)
{
if (Char.IsLower(ch)) temp += Char.ToUpper(ch);
else temp += Char.ToLower(ch);
}
return temp;
}
// Return the absolute value of n / d.
public static double AbsDivideBy(this double n, double d)
{
return Math.Abs(n / d);
}
}
class ExtDemo
{
static void Main()
{
double val = 8.0;
string str = "Alpha Beta Gamma";
// Call the Recip() extension method.
Console.WriteLine("Reciprocal of {0} is {1}", val, val.Reciprocal());
// Call the RevCase() extension method.
Console.WriteLine(str + " after reversing case is " + str.RevCase());
// Use AbsDivideBy();
Console.WriteLine("Result of val.AbsDivideBy(-2): " + val.AbsDivideBy(-2));
}
}
The output is shown here:
Reciprocal of 8 is 0.125
Alpha Beta Gamma after reversing case is aLPHA bETA gAMMA
Result of val.AbsDivideBy(-2): 4
In the program, notice that each extension method is contained in a static class called MyExtMeths. As explained, an extension method must be declared within a static class. Furthermore, this class must be in scope in order for the extension methods that it contains to be used. (This is why you need to include the System.Linq namespace when using LINQ.)
Next, notice the calls to the extension methods. They are invoked on an object in just the same way that an instance method is called. The main difference is that the invoking object is passed to the first parameter of the extension method. Therefore, when the expression
val.AbsDivideBy(-2))
executes, val is passed to the n parameter of AbsDivideBy( ) and –2 is passed to the d parameter.
As a point of interest, because the methods Reciprocal( ) and AbsDivideBy( ) are defined for double, it is legal to invoke them on a double literal, as shown here:
8.0.Reciprocal()
8.0.AbsDivideBy(-1)
Furthermore, RevCase( ) can be invoked like this:
"AbCDe".RevCase()
Here, the reversed-case version of a string literal is returned.
What is sealed class?
To prevent a class from being inherited, precede its declaration with sealed.
Sometimes you want to prevent a class from being inherited. For example, you might have a class that encapsulates the initialization sequence of some specialized hardware device, such as a medical monitor. In this case, you don’t want users of your class to be able to change the way the monitor is initialized, possibly setting the device incorrectly. Whatever the reason, in C# it is easy to prevent a class from being inherited by using the keyword sealed.
It is illegal to declare a class as both abstract and sealed because an abstract class is incomplete by itself and relies upon its derived classes to provide complete implementations.
Sealed can also be used on virtual methods to prevent further overrides. For example, assume a base class called B and a derived class called D. A method declared virtual in B can be declared sealed by D. This would prevent any class that inherits D from overriding the method.
class B
{
public virtual void MyMethod() { /* ... */ }
}
class D : B
{
// This seals MyMethod() and prevents further overrides.
sealed public override void MyMethod() { /* ... */ }
}
class X : D
{
// Error! MyMethod() is sealed!
public override void MyMethod() { /* ... */ }
}
Because MyMethod( ) is sealed by D, it can’t be overridden by X.
Which method is used to enforce garbage collector to collect explicitly?
Use the G.C.SuppressFinalize () method to suppress the finalize process inside the garbage collector forcibly in.Net.
What is lazy initialization?
Lazy initialization is a process by which an object is not initialized until it is first called in your code. The .Net 4.0 introduces a new wrapper class, System. Lazy<T>, for executing the lazy initialization in your application. Lazy initialization helps you to reduce the wastage of resources and memory requirement to improve performance. It also supports thread-safety.
What is encapsulation ?
Encapsulation is the ability to contain and control access to a group of associated items. Classes provide one of the most common ways to encapsulate items. For example, the BankAccount class encapsulates the methods, fields, and properties that describe a bank account.
Without encapsulation, you would declare separate procedures and variables to store and manage information for the bank account, and it would be difficult for you to work with more than one bank account at a time. With encapsulation you can use the data and procedures in the BankAccount class as a unit. You can work with multiple bank accounts at the same time without confusion because each account is represented by a unique instance of the class.
Encapsulation also allows you to control how the data and procedures are used. You can use access modifiers, such as Private or Protected, to prevent outside procedures from executing class methods or reading and modifying data in properties and fields. You should declare internal details of a class as Private to prevent them from being used outside of your class; this technique is called data hiding, and is how customer information such as the account balance is protected.
One basic rule of encapsulation is that class data should be modified or retrieved only via Property, procedures or methods. Hiding the implementation details of your classes prevents classes from being used in undesired ways, and lets you to later modify such items without risk of compatibility problems. For example, later versions of the BankAccount class could change the data type of the AccountBalance field without breaking other applications that rely on this field having a specific data type.
OR
Encapsulation is a programming mechanism that binds together code and the data it manipulates, and that keeps both safe from outside interference and misuse. In an object oriented language, code and data can be bound together in such a way that a self-contained black box is created. Within the box are all necessary data and code. When code and data are linked together in this fashion, an object is created. In other words, an object is the device that supports encapsulation.
Within an object, the code, data, or both may be private to that object or public. Private code or data is known to and accessible by only another part of the object. That is, private code or data cannot be accessed by a piece of the program that exists outside the object. When code or data is public, other parts of your program can access it even though it is defined within an object. Typically, the public parts of an object are used to provide a controlled interface to the private elements.
C#’s basic unit of encapsulation is the class. A class defines the form of an object. It specifies both the data and the code that will operate on that data. C# uses a class specification to construct objects. Objects are instances of a class. Thus, a class is essentially a set of plans that specify how to build an object.
Collectively, the code and data that constitute a class are called its members. The data defined by the class is referred to as fields. The terms member variables and instance variables also are used. The code that operates on that data is contained within function members, of which the most common is the method. Method is C#’s term for a subroutine. (Other function members include properties, events, and constructors.) Thus, the methods of a class contain code that acts on the fields defined by that class.
What is Polymorphism?
Polymorphism allows one interface to access a general class of actions. A simple example of polymorphism is found in the steering wheel of an automobile. The steering wheel (the interface) is the same no matter what type of actual steering mechanism is used. That is, the steering wheel works the same whether your car has manual steering, power steering, or rack-and-pinion steering. Thus, turning the steering wheel left causes the car to go left no matter what type of steering is used. The benefit of the uniform interface is, of course, that once you know how to operate the steering wheel, you can drive any type of car.
The same principle can also apply to programming. For example, consider a stack (which is a first-in, last-out list). You might have a program that requires three different types of stacks. One stack is used for integer values, one for floating-point values, and one for characters. In this case, the algorithm that implements each stack is the same, even though the data being stored differs. In a non-object-oriented language, you would be required to create three different sets of stack routines, with each set using different names. However, because of polymorphism, in C# you can create one general set of stack routines that works for all three specific situations. This way, once you know how to use one stack, you can use them all.
More generally, the concept of polymorphism is often expressed by the phrase “one interface, multiple methods.” This means that it is possible to design a generic interface to a group of related activities. Polymorphism helps reduce complexity by allowing the same interface to be used to specify a general class of action. It is the compiler’s job to select the specific action (that is, method) as it applies to each situation. You, the programmer, don’t need to do this selection manually. You need only remember and utilize the general interface.
What is Inheritance?
Inheritance is the process by which one object can acquire the properties of another object. This is important because it supports the concept of hierarchical classification. If you think about it, most knowledge is made manageable by hierarchical (that is, top-down) classifications. For example, a Red Delicious apple is part of the classification apple, which in turn is part of the fruit class, which is under the larger class food. That is, the foodclass possesses certain qualities (edible, nutritious, and so on) which also, logically, apply to its subclass, fruit.In addition to these qualities, the fruit class has specific characteristics (juicy, sweet, and so on) that distinguish it from other food. The apple class defines those qualities specific to an apple (grows on trees, not tropical, and so on). A Red Delicious apple would, in turn, inherit all the qualities of all preceding classes and would define only those qualities that make it unique.
Without the use of hierarchies, each object would have to explicitly define all of its characteristics. Using inheritance, an object need only define those qualities that make it unique within its class. It can inherit its general attributes from its parent. Thus, the inheritance mechanism makes it possible for one object to be a specific instance of a more general case.
What is an abstraction in OOPs?
Abstraction means to show only the necessary details to the client of the object. It simply means showing only those details to the user which are of use to them, and hiding up the unnecessary portion.
For example do you know the inner details of the Monitor of your PC? What happen when you switch ON Monitor? Does this matter to you what is happening inside the Monitor? No Right, Important thing for you is weather Monitor is ON or NOT. When you change the gear of your vehicle are you really concern about the inner details of your vehicle engine? No but what matter to you is that Gear must get changed that’s it!! This is abstraction; show only the details which matter to the user.
Let’s say you have a method "CalculateSalary" in your Employee class, which takes EmployeeId as parameter and returns the salary of the employee for the current month as an integer value. Now if someone wants to use that method. He does not need to care about how Employee object calculates the salary? An only thing he needs to be concern is name of the method, its input parameters and format of resulting member, Right?
So abstraction says expose only those details which are concern with the user (client) of your object. So the client who is using your class need not to be aware of the inner details like how you class do the operations? He needs to know just few details. This certainly helps in reusability of the code.
So abstraction says expose only those details which are concern with the user (client) of your object. So the client who is using your class need not to be aware of the inner details like how you class do the operations? He needs to know just few details. This certainly helps in reusability of the code.
The best thing of abstract is that this decouples the user of the object and its implementation. So now object is easy to understand and maintain also. As if there is any change in the process of some operation. You just need to change the inner details of a method, which have no impact on the client of class.
What is the difference between strong typing and weak typing in .NET?
Strong typing means that the type check is done at compile time and weak typing means that the type check is done at run time. .NET languages incorporate strong typing.
Every variable in .NET should have a type associated and the value assigned to the variable should match its type. If these rules are violated then compile time error will be displayed. This avoids error messages to be displayed to the User at run time. Consider the following example:
public class sampleClass {
public static void Main() {
sampleNo = 10;
}
}
public static void Main() {
sampleNo = 10;
}
}
In this example, the variable sampleNo is not declared with any type. This will be detected by the compiler during compilation and you will get the following error:
“The name ‘sampleNo’ does not exist in the current context”
Also, the value assigned to the variable should be acceptable by the type. Consider the following example:
public class sampleClass {
public static void Main() {
int sampleNo=10;
string sampleStr = 100;
}
}
public static void Main() {
int sampleNo=10;
string sampleStr = 100;
}
}
In this example, note that the statement “int sampleNo = 10” is legal because you create a variable sampleNo, declare its type to Integer and define its value to be 10, an integer value. But the next statement “string sampleStr=100” is incorrect because you create a variable called sampleStr, declare its type to String and define its value to be 100, an integer value instead of string value. Hence during compilation, you will get the following error:
“Cannot implicitly convert ‘int’ to ‘string’”
“Cannot implicitly convert ‘int’ to ‘string’”
However there are situations when you cannot associate the actual type to a variable at compile time itself. In such cases, you can declare the variable with type var in C# version 3.0 or higher. Such variables can hold values of any type and the actual type will be associated at run time.
Explain exception handling. How to use it?
A try block is used by C# programmers to partition code that might be affected by an exception. Associated catch blocks are used to handle any resulting exceptions. A finally block contains code that is run regardless of whether or not an exception is thrown in the
try
block, such as releasing resources that are allocated in the try
block. A try
block requires one or more associated catch
blocks, or a finally
block, or both.
The following examples show a
try-catch
statement, a try-finally
statement, and a try-catch-finally
statement.try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
// Only catch exceptions that you know how to handle.
// Never catch base class System.Exception without
// rethrowing it at the end of the catch block.
}
try
{
// Code to try goes here.
}
finally
{
// Code to execute after the try block goes here.
}
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
}
finally
{
// Code to execute after the try (and possibly catch) blocks
// goes here.
}
A
try
block without a catch
or finally
block causes a compiler error.
Catch Blocks
A
catch
block can specify the type of exception to catch. The type specification is called an exception filter. The exception type should be derived from Exception. In general, do not specify Exception as the exception filter unless either you know how to handle all exceptions that might be thrown in the try
block, or you have included a throw statement at the end of your catch
block.
Multiple
catch
blocks with different exception filters can be chained together. The catch
blocks are evaluated from top to bottom in your code, but only one catch
block is executed for each exception that is thrown. The first catch
block that specifies the exact type or a base class of the thrown exception is executed. If no catch
block specifies a matching exception filter, a catch
block that does not have a filter is selected, if one is present in the statement. It is important to position catch
blocks with the most specific (that is, the most derived) exception types first.
You should catch exceptions when the following conditions are true:
· You have a good understanding of why the exception might be thrown, and you can implement a specific recovery, such as prompting the user to enter a new file name when you catch a FileNotFoundException object.
· You can create and throw a new, more specific exception.
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch(System.IndexOutOfRangeException e)
{
throw
new System.ArgumentOutOfRangeException(
"Parameter index is out of range.", e);
}
}
· You want to partially handle an exception before passing it on for additional handling. In the following example, a
catch
block is used to add an entry to an error log before re-throwing the exception.
try
{
// Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
// Call a custom error logging procedure.
LogError(e);
// Re-throw the error.
throw;
}
Finally Blocks
A
finally
block enables you to clean up actions that are performed in a try
block. If present, the finally
block executes last, after the try
block and any matched catch
block. A finally
block always runs, regardless of whether an exception is thrown or a catch
block matching the exception type is found.
The
finally
block can be used to release resources such as file streams, database connections, and graphics handles without waiting for the garbage collector in the runtime to finalize the objects.
In the following example, the
finally
block is used to close a file that is opened in the try
block. Notice that the state of the file handle is checked before the file is closed. If the try
block cannot open the file, the file handle still has the value null
and the finally
block does not try to close it. Alternatively, if the file is opened successfully in the try
block, the finally
block closes the open file.System.IO.FileStream file =
null;
System.IO.FileInfo fileinfo =
new System.IO.FileInfo(
"C:\\file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(
0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
if (file !=
null)
{
file.Close();
}
}
Creating and Throwing Exceptions
Exceptions are used to indicate that an error has occurred while running the program. Exception objects that describe an error are created and then thrown with the throw keyword. The runtime then searches for the most compatible exception handler.
Programmers should throw exceptions when one or more of the following conditions are true:
· The method cannot complete its defined functionality.
For example, if a parameter to a method has an invalid value:
static void CopyObject(SampleClass original)
{
if (original ==
null)
{
throw
new System.ArgumentException(
"Parameter cannot be null",
"original");
}
}
· An inappropriate call to an object is made, based on the object state.
One example might be trying to write to a read-only file. In cases where an object state does not allow an operation, throw an instance of InvalidOperationException or an object based on a derivation of this class. This is an example of a method that throws an InvalidOperationException object:
class
ProgramLog
{
System.IO.FileStream logFile =
null;
void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}
void WriteLog()
{
if (!
this.logFile.CanWrite)
{
throw
new System.InvalidOperationException(
"Logfile cannot be read-only");
}
// Else write data to the log and return.
}
}
· When an argument to a method causes an exception.
In this case, the original exception should be caught and an ArgumentException instance should be created. The original exception should be passed to the constructor of the ArgumentException as the InnerException parameter:
static int GetValueFromArray(int[] array, int index)
{
try
{
return array[index];
}
catch (System.IndexOutOfRangeException ex)
{
System.ArgumentException argEx =
new System.ArgumentException(
"Index is out of range",
"index", ex);
throw argEx;
}
}
Exceptions contain a property named StackTrace. This string contains the name of the methods on the current call stack, together with the file name and line number where the exception was thrown for each method. A StackTrace object is created automatically by the common language runtime (CLR) from the point of the
throw
statement, so that exceptions must be thrown from the point where the stack trace should begin.
All exceptions contain a property named Message. This string should be set to explain the reason for the exception. Note that information that is sensitive to security should not be put in the message text. In addition to Message, ArgumentException contains a property named ParamName that should be set to the name of the argument that caused the exception to be thrown. In the case of a property setter, ParamName should be set to
value
.
Public and protected methods should throw exceptions whenever they cannot complete their intended functions. The exception class that is thrown should be the most specific exception available that fits the error conditions. These exceptions should be documented as part of the class functionality, and derived classes or updates to the original class should retain the same behaviour for backward compatibility.
Things to Avoid When Throwing Exceptions
The following list identifies practices to avoid when throwing exceptions:
· Exceptions should not be used to change the flow of a program as part of ordinary execution. Exceptions should only be used to report and handle error conditions.
· Exceptions should not be returned as a return value or parameter instead of being thrown.
· Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.
· Do not create exceptions that can be thrown in debug mode but not release mode. To identify run-time errors during the development phase, use Debug Assert instead.
Compiler-Generated Exceptions
Some exceptions are thrown automatically by the .NET Framework's common language runtime (CLR) when basic operations fail. These exceptions and their error conditions are listed in the following table.
Exception
|
Description
|
ArithmeticException
|
A base class for exceptions that occur during arithmetic operations, such as DivideByZeroException and OverflowException.
|
ArrayTypeMismatchException
|
Thrown when an array cannot store a given element because the actual type of the element is incompatible with the actual type of the array.
|
DivideByZeroException
|
Thrown when an attempt is made to divide an integral value by zero.
|
IndexOutOfRangeException
|
Thrown when an attempt is made to index an array when the index is less than zero or outside the bounds of the array.
|
InvalidCastException
|
Thrown when an explicit conversion from a base type to an interface or to a derived type fails at runtime.
|
NullReferenceException
|
Thrown when you attempt to reference an object whose value is null.
|
OutOfMemoryException
|
Thrown when an attempt to allocate memory using the new operator fails. This indicates that the memory available to the common language runtime has been exhausted.
|
OverflowException
|
Thrown when an arithmetic operation in a checked context overflows.
|
StackOverflowException
|
Thrown when the execution stack is exhausted by having too many pending method calls; usually indicates a very deep or infinite recursion.
|
TypeInitializationException
|
Thrown when a static constructor throws an exception and no compatible catch clause exists to catch it.
|
How to: Catch a non-CLS Exception
Some .NET languages, including C++/CLI, allow objects to throw exceptions that do not derive from Exception. Such exceptions are called non-CLS exceptions or non-Exceptions. In C# you cannot throw non-CLS exceptions, but you can catch them in two ways:
· Within a
catch (RuntimeWrappedException e)
block.
By default, a Visual C# assembly catches non-CLS exceptions as wrapped exceptions. Use this method if you need access to the original exception, which can be accessed through the RuntimeWrappedException.WrappedException property.
Within a general catch block (a catch block without an exception type specified) that is put after all other
catch
blocks.
Use this method when you want to perform some action (such as writing to a log file) in response to non-CLS exceptions, and you do not need access to the exception information. By default the common language runtime wraps all exceptions. To disable this behavior, add this assembly-level attribute to your code, typically in the AssemblyInfo.cs file:
[assembly:
RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)]
.
To catch a non-CLS exception
Within a
catch(RuntimeWrappedException e)
block, access the original exception through the RuntimeWrappedException.WrappedException property.
Example
The following example shows how to catch a non-CLS exception that was thrown from a class library written in C++/CLI. Note that in this example, the C# client code knows in advance that the exception type being thrown is a System.String. You can cast the RuntimeWrappedException.WrappedException property back its original type as long as that type is accessible from your code.
// Class library written in C++/CLI.
var myClass =
new ThrowNonCLS.Class1();
try
{
// throws gcnew System::String(
// "I do not derive from System.Exception!");
myClass.TestThrow();
}
catch (RuntimeWrappedException e)
{
String s = e.WrappedException
as String;
if (s !=
null)
{
Console.WriteLine(s);
}
}
What is Reflection?
Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.
Here's a simple example of reflection using the static method
GetType
- inherited by all types from the Object
base class - to obtain the type of a variable:// Using GetType to obtain type information:
int i =
42;
System.Type type = i.GetType();
System.Console.WriteLine(type);
The output is:
System.Int32
The following example uses reflection to obtain the full name of the loaded assembly.
// Using Reflection to get information from an Assembly:
System.Reflection.Assembly info =
typeof(System.Int32).Assembly;
System.Console.WriteLine(info);
The output is:
mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Note
The C# keywords and
protected
internal
have no meaning in IL and are not used in the reflection APIs. The corresponding terms in IL are Family and Assembly. To identify an internal
metho using reflection, use the IsAssembly property. To identify a protected
internal
method, use the IsFamilyOrAssembly.
Reflection Overview
Reflection is useful in the following situations:
· When you have to access attributes in your program's metadata.
· For examining and instantiating types in an assembly.
· For building new types at runtime. Use classes in System.Reflection.Emit.
· For performing late binding, accessing methods on types created at run time.
Access Modifiers and Access Levels
All classes and class members can specify what access level they provide to other classes by using access modifiers.
The following access modifiers are available:
C# Modifier
|
Definition
|
public
|
The type or member can be accessed by any other code in the same assembly or another assembly that references it.
|
private
|
The type or member can only be accessed by code in the same class.
|
protected
|
The type or member can only be accessed by code in the same class or in a derived class.
|
internal
|
The type or member can be accessed by any code in the same assembly, but not from another assembly.
|
protected internal
|
The type or member can be accessed by any code in the same assembly, or by any derived class in another assembly.
|
private protected
|
The type or member can be accessed by code in the same class or in a derived class within the base class assembly.
|
Garbage Collection
.NET's garbage collector manages the allocation and release of memory for your application. Each time you create a new object, the common language runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually, the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory.
Generations of Garbage Collection
The heap is organized into generations so it can handle long-lived and short-lived objects. Garbage collection primarily occurs with the reclamation of short-lived objects that typically occupy only a small part of the heap. There are three generations of objects on the heap:
· Generation 0. This is the youngest generation and contains short-lived objects. An example of a short-lived object is a temporary variable. Garbage collection occurs most frequently in this generation.
Newly allocated objects form a new generation of objects and are implicitly generation 0 collections unless they are large objects, in which case they go on the large object heap in a generation 2 collection.
Most objects are reclaimed for garbage collection in generation 0 and do not survive to the next generation.
· Generation 1. This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects.
· Generation 2. This generation contains long-lived objects. An example of a long-lived object is an object in a server application that contains static data that is live for the duration of the process.
Garbage collections occur on specific generations as conditions warrant. Collecting a generation means collecting objects in that generation and all its younger generations. A generation 2 garbage collection is also known as a full garbage collection because it reclaims all objects in all generations (that is, all objects in the managed heap).
Survival and promotions in Garbage Collection
Objects that are not reclaimed in a garbage collection are known as survivors, and are promoted to the next generation. Objects that survive a generation 0 garbage collection are promoted to generation 1; objects that survive a generation 1 garbage collection are promoted to generation 2; and objects that survive a generation 2 garbage collection remain in generation 2.
When the garbage collector detects that the survival rate is high in a generation, it increases the threshold of allocations for that generation, so the next collection gets a substantial size of reclaimed memory. The CLR continually balances two priorities: not letting an application's working set get too big and not letting the garbage collection take too much time.
Weak References in Garbage Collection
The garbage collector cannot collect an object in use by an application while the application's code can reach that object. The application is said to have a strong reference to the object.
A weak reference permits the garbage collector to collect the object while still allowing the application to access the object. A weak reference is valid only during the indeterminate amount of time until the object is collected when no strong references exist. When you use a weak reference, the application can still obtain a strong reference to the object, which prevents it from being collected. However, there is always the risk that the garbage collector will get to the object first before a strong reference is re-established.
Weak references are useful for objects that use a lot of memory but can be recreated easily if they are reclaimed by garbage collection.
No comments:
Post a Comment