- What are Jagged Arrays?
- What is serialization?
- What are Custom Control and User Control?
- Explain Reflection in C#.
- Give a brief explanation on Thread Pooling in C#.
- Why do we use Async and Await in C#?
- What is Managed and Unmanaged code?
- Explain Polymorphism?
- Explain Namespaces in C#.
- What are the basic String Operations? Explain.
- What is a Thread? What is Multithreading?
- What is a Deadlock?
- What is a Race Condition?
- What are Properties in C#?
- What are extension methods in C#?
- What's a multicast delegate?
- What are circular references?
- What is method overloading?
- What do you understand by Get and Set Accessor properties?
- What is scope of a Protected Internal member variable of a C# class?
- What are the differences between a class and structure?
- What is the use of conditional preprocessor directive in C#?
- Can you pass additional type of parameters after using params in function definition?
- What is a enumeration in C#?
- What are the advantages of using C#?
- What are the different approaches of passing parameters to a method?
- Distinguish between finally and finalize blocks?
- Define a Partial class?
- What is boxing?
- Why can't you specify the accessibility modifier for methods inside the interface?
- Distinguish between System.String and System.Text.StringBuilder classes?
- List down the differences between “dispose” and “finalize” methods in C#.
- What is Thread Pooling?
- Illustrate Serialization.
- What is the lock statement in C#?
- Which are the access modifiers available in C#?
- What is object pool in .Net?
- What is Garbage Collection?
- Explain sealed class in C#?
- List out the differences between Array and ArrayList in C#?
- What are the differences between events and delegates in C#?
- Explain Attributes in C#?
- What is Method Hiding in C#?
- What is Abstract Class in C#?
- What is an Interface in C#?
- What is a Constructor in C#?
- Explain nullable types in C#.
- Explain the role of structs in C#. Why would you choose to define a type as a struct instead of a class?
- What are some of the features of generics in C#?
- What are delegates and its types in C#?
- Can you change the value of a variable while debugging a c# application?
- What is a pre-requisite for connection pooling?
- Can I call a virtual method from a constructor/destructor?
- Does C# support a variable number of arguments?
- Can an interface inherit from another interface?
- What are the advantages of using partial classes?
- Is it possible to force garbage collector to run?
- Usually in .NET, the clr takes care of memory management. Is there any need for a programmer to explicitly release memory and resources? If yes, why and how?
- Structs are not reference types. Can structs have constructors?
- Give 2 scenarios where static constructors can be used?
- Can you declare a class or a struct as constant?
- What are instance fields in c#?
- What does protected internal access modifier mean?
- What are the differences between value types and reference types?
- What is Unboxing?
- What happens during the process of boxing?
- Explain String immutability in C#.
- Can you serialize hashtable and Why?
- What are extension methods?
- What is the difference between dynamic type variables and object type variables?
- What are some of the advantages of using C#? Which features do you find most useful?
- Can we create derived class object from base class C#?
- Do structs support inheritance?
- When do you generally use a class over a struct?
- What happens if you inherit multiple interfaces and they have conflicting method names?
- If a base class has a number of overloaded constructors, and an inheriting class has a number of overloaded constructors; can you enforce a call from an inherited constructor to a specific base constructor?
- Is it possible to have different access modifiers on the get/set methods of a property?
- What's the difference between private and shared assembly?
- Why do I get a security exception when I try to run my c# app?
- Does C# support templates?
- Does C# support parameterized properties?
- How do I get deterministic finalization in C#?
- How do I create a delegate/multicastdelegate?
- What is the difference between imperative and interrogative code?
- What is Constructor?
- What is Destructor?
- What are Generics in C#?
- Can you explain the concept of inner exception in C#?
- State the difference between direct cast and ctype.
- How can one use the singleton design pattern in C#?
- What does the term thread mean?
- Structs are largely redundant in c++. Why does c# have them?
- Are C# destructors the same as C++ destructors?
- What is marshalling and why do we need it?
- Can Multiple Inheritance be implemented in C# ?
- Could you explain the difference between Func vs. Action vs. Predicate?
- What is the advantage of Immutable String?
The Array which has elements of type array is called jagged Array. The elements can be of different dimensions and sizes. We can also call jagged Array as an Array of arrays.
When we want to transport an object through a network, then we have to convert the object into a stream of bytes. The process of converting an object into a stream of bytes is called Serialization. For an object to be serializable, it should implement ISerialize Interface. De-serialization is the reverse process of creating an object from a stream of bytes.
Custom Controls are controls generated as compiled code (Dlls), those are easier to use and can be added to toolbox. Developers can drag and drop controls to their web forms. Attributes can, at design time. We can easily add custom controls to Multiple Applications (If Shared Dlls). So, If they are private, then we can copy to dll to bin directory of web application and then add reference and can use them.
User Controls are very much similar to ASP include files, and are easy to create. User controls can't be placed in the toolbox and dragged - dropped from it. They have their design and code-behind. The file extension for user controls is ascx.
The ability of code to access the metadata of the assembly during runtime is called Reflection. A program reflects upon itself and uses the metadata to:
- Inform the user, or
- Modify the behavior
The system contains all classes and methods that manage the information of all the loaded types and methods. Reflection namespace. Implementation of reflection is in 2 steps:
- Get the type of the object, then
- Use the type to identify members, such as properties and methods
A collection of threads, termed as a Thread Pool in C#. Such threads are for performing tasks without disturbing the execution of the primary thread. After a thread belonging to a thread pool completes execution, it returns to the thread pool. Classes that manage the thread in the thread pool, and its operations, are contained in the System.Threading.ThreadPool namespace.
Processes belonging to asynchronous programming run independently of the main or other processes. In C#, using Async and Await keywords for creating asynchronous methods.
Managed code is a code that is executed by CLR (Common Language Runtime) i.e all application code is based on .Net platform. It is considered as managed because of the .Net framework which internally uses the garbage collector to clear up the unused memory.
Unmanaged code is any code that is executed by application runtime of any other framework apart from .Net. The application runtime will take care of memory, security and other performance operations.
Programmatically, Polymorphism means the same method but different implementations. It is of 2 types, Compile-time and Runtime.
- Compile-time polymorphism is achieved by operator overloading.
- Runtime polymorphism is achieved by overriding. Inheritance and Virtual functions are used during Runtime polymorphism.
For Example, If a class has a method Void Add(), polymorphism is achieved by overloading the method, that is, void Add(int a, int b), void Add(int add) are all overloaded methods.
They are used to organize large code projects. “System” is the most widely used namespace in C#. We can create our own namespace and can also use one namespace in another, which is called Nested Namespaces.
Some of the basic string operations are:
- Concatenate: Two strings can be concatenated either by using a System.String.Concat or by using + operator.
- Modify: Replace(a,b) is used to replace a string with another string. Trim() is used to trim the string at the end or at the beginning.
- Compare: System.StringComparison() is used to compare two strings, either a case-sensitive comparison or not case sensitive. Mainly takes two parameters, original string, and string to be compared with.
- Search: StartWith, EndsWith methods are used to search a particular string.
A Thread is a set of instructions that can be executed, which will enable our program to perform concurrent processing. Concurrent processing helps us do more than one operation at a time. By default, C# has only one thread. But the other threads can be created to execute the code in parallel with the original thread. Thread has a life cycle. It starts whenever a thread class is created and is terminated after the execution. System.Threading is the namespace which needs to be included to create threads and use its members.
C# can execute more than one task at a time. This is done by handling different processes by different threads. This is called MultiThreading.
A Deadlock is a situation where a process is not able to complete its execution because two or more processes are waiting for each other to finish. This usually occurs in multi-threading.
Here a shared resource is being held by a process and another process is waiting for the first process to release it and the thread holding the locked item is waiting for another process to complete.
Race condition occurs when two threads access the same resource and are trying to change it at the same time. The thread which will be able to access the resource first cannot be predicted.
If we have two threads, T1 and T2, and they are trying to access a shared resource called X. And if both the threads try to write a value to X, the last value written to X will be saved.
C# properties are members of a C# class that provide a flexible mechanism to read, write or compute the values of private fields, in other words, by using properties, we can access private fields and set their values. Properties in C# are always public data members. C# properties use get and set methods, also known as accessors, to access and assign values to private fields.
Extension methods enable you to add methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
An extension method is a special kind of static method, but they are called as if they were instance methods on the extended type.
A delegate having multiple handlers assigned to it is called multicast delegate. Each handler is assigned to a method.
Circular reference is situation in which two or more resources are interdependent on each other causes the lock condition and make the resources unusable.
Method overloading is creating multiple methods with the same name with unique signatures in the same class. When we compile, the compiler uses overload resolution to determine the specific method to be invoke.
Made using properties, Get and Set are called accessors in C#. A property enables reading and writing to the value of a private field. Accessors are used for accessing such private fields. While we use the Get property for returning the value of a property, use the Set property for setting the value.
The protected internal access specifier allows a class to hide its member variables and member functions from other class objects and functions, except a child class within the same application. This is also used while implementing inheritance.
Classes and Structures have the following basic differences: - classes are reference types and structs are value types. - structures do not support inheritance. - structures cannot have default constructor.
You can use the #if directive to create a conditional directive. Conditional directives are useful for testing a symbol or symbols to check if they evaluate to true. If they do evaluate to true, the compiler evaluates all the code between the #if and the next directive.
No! additional parameters are not permitted after the params keyword in a method declaration. Only one params keyword is allowed in a method declaration.
An enumeration is a set of named integer constants. An enumerated type is declared using the enum keyword. C# enumerations are value data type. In other words, enumeration contains its own values and cannot inherit or cannot pass inheritance.
Following are the advantages of using C#:
- Easy to learn
- Object-Oriented language
- The syntax is easy to grasp
- Component oriented
- Part of the .NET framework
There are three ways of passing parameters to a method:
- Value Parameters- Under this method the actual value of an argument is copied to the formal parameter of the function. In, this case the changes made into the formal parameter of the function have no effect on the actual value of the argument.
- Reference Parameters- This method copies the argument referring to the memory location into the formal parameter. Meaning changes made to the parameter affect the argument.
- Output Parameters- This method returns more than one value.
finally block is called after the execution of try and catch blocks, It is used for exception handling whether or not the exception has been caught this block of code gets executed. Generally, this block of code has a cleaner code.
The finalize method is called just before the garbage collection. Main priorities are to perform clean up operation for unmanaged code, it is automatically invoked when an instance is not subsequently called.
A partial class is the only one that essentially splits the definition of a class into multiple classes in either same source code files or multiple source code files. One can create a class definition in multiple files but that is compiled as one class at run-time and when an instance of this class is created, one can access all methods from every source file with the same object. It is indicated by the keyword ‘partial’.
Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by the value type. Boxing a value type creates an object instance containing the value and stores it on the heap.
Why can't you specify the accessibility modifier for methods inside the interface?
System.String is immutable. Whenever you modify the value of a string variable then a new memory is allocated to the new value and previous memory allocation is released. System.Text.StringBuilder is mutable i.e. supports the fact that a variety of operations can be performed without allocating a seperate memory location for the already modified string.
Dispose() is called when we want an object to release unmanaged resources with them. Whereas, Finalize() is used for the same purpose but it doesn’t assure garbage collection of an object.
A Thread pool is a collection of threads that perform tasks without disturbing the primary thread. Once the task is completed by a thread it returns to the primary thread.
A process that involves converting some code into its binary format is known as a serialization in C#. In doing so it gives the flexibility where code can be stored easily and or written to a disk or some other storage device. Serialization is used when there is a strict need for not losing the original code.
Serialization in C# is of three types:
- Binary Serialization- It is fast and demands less space, converts any code into its binary format. Serialize and restore public and non-public properties.
- SOAP- Generates a complete SOAP compliant envelope used by any system by its ability to understand SOAP. Classes under this type of Serialization reside in System.Runtime.Serialization.
- XML Serialization- It serializes all the public properties to XML document. Readability being one factor, an XML document can also be manipulated in various ways. Classes under this type reside in System.sml.Serialization.
Lock statement is used to ensure that one thread doesn't enter a critical section of code while another thread is in the critical section. If another thread attempts to enter a locked code it will wait, block, until the object is released.
Following are the access modifiers generally used for accessibility:
- Public: If you define an attribute or method as public, it can be accessed from any code of the project.
- Private: A private defined attribute or method can be accessed by any code within the containing class only.
- Protected: If you define the method or attribute as protected it can be accessed by any method in the inherited classes and any method within the same class.
- Internal: If you define an attribute or a method as internal, it is restricted to classes within the current position assembly.
- Protected internal: If you define an attribute or method as protected internal, access is restricted to classes within the current project assembly or types derived from the containing class.
Object pool is a container of ready to use objects. It reduces the overhead of creating new object.
Garbage Collection is a process of releasing memory automatically occupied by objects which are no longer accessible.
Sealed class is used to prevent the class from being inherited from other classes. So “sealed” modifier also can be used with methods to avoid the methods to override in the child classes.
- Array stores the values or elements of same data type but arraylist stores values of different datatypes.
- Arrays will use the fixed length but arraylist does not uses fixed length like array.
Main difference between event and delegate is event will provide one more of encapsulation over delegates. So when you are using events destination will listen to it but delegates are naked, which works in subscriber/destination model.
- Attributes are used to convey the info for runtime about the behavior of elements like – “methods”, “classes”, “enums” etc.
- Attributes can be used to add metadata like – comments, classes, compiler instruction etc.
If the derived class doesn't want to use methods in the base class, derived class can implement it's own version of the same method with same signature. If the derived class doesn't want to use methods in the base class, derived class can implement it's own version of the same method with same signature. This is called Method Hiding.
If we don't want a class to be instantiated, define the class as abstract. An abstract class can have abstract and non abstract classes. If a method is defined as abstract, it must be implemented in derived class.
An interface is similar to a class with method signatures. There wont be any implementation of the methods in an Interface. Classes which implement interface should have an implementation of methods defined in the abstract class.
Constructor is a special method that get invoked/called automatically, whenever an object of a given class gets instantiated. In our class car, constructor is defined as shown below
Nullable types are data types that, in addition to their normal values, also contain a defined data type for null. Nullable types exist to help integrate C#, which generally works with value types, and databases, which often use null values.
Structs are used to create structures, a value type that is used to represent a record. Structs play a similar role to classes, which are a reference type in C#. Since structs are value types, they are allocated and deallocated on the stack or inline in containing types. This generally makes structs cheaper to allocate or deallocate than classes, which are reference types. Reference types are allocated on the heap and garbage-collected, which tends to take up more resources. If the instances of a type are small and short-lived, it makes sense to define a value type using structs. The opposite is true when it comes to boxing and unboxing. A value type can get boxed when it is cast to a reference type or some other interface it implements. Because boxes are objects allocated to the heap and deallocated via garbage collection, too much boxing and unboxing of a value can negatively impact performance. Reference types like classes are preferred in these situations.
Generics allow a developer to define a class or method that can work with virtually any data type by delaying specification of the programming elements' data types until they are needed. Generics come with a number of features.
- They make C# code reusable, type safe, and performance optimized.
- They allow the developer to create generic classes, methods, events, delegates, and interfaces.
- They allow the developer to create generic collection classes in the System.Collections.Generic namespace.
- They make it possible to get real-time information on the types used in a generic data type at runtime via reflection.
Delegates are type-safe objects containing information about the function rather than data. They can define their own type parameters
Below are the types of delegates in C#:
- Single Delegate -used to invoke a single method.
- Multicast Delegate -used to invoke multiple methods on existing delegate instance using the + operator and – operator. However, the methods will be invoked in sequence as they are assigned.
- Generic Delegate -used to invoke a single method that doesn’t require to define the delegate instance. There are 3 types of generic delegates: Func, Action, and Predicate.
Yes, if you are debugging via Visual Studio.NET, just go to Immediate window.
Multiple processes must agree that they will share the same connection, where every parameter is the same, including the security settings.
Yes, but it's generally not a good idea. The mechanics of object construction in .NET are quite different from C++, and this affects virtual method calls in constructors.
C++ constructs objects from base to derived, so when the base constructor is executing the object is effectively a base object, and virtual method calls are routed to the base class implementation. By contrast, in .NET the derived constructor is executed first, which means the object is always a derived object and virtual method calls are always routed to the derived implementation. (Note that the C# compiler inserts a call to the base class constructor at the start of the derived constructor, thus preserving standard OO semantics by creating the illusion that the base constructor is executed first.)
The same issue arises when calling virtual methods from C# destructors. A virtual method call in a base destructor will be routed to the derived implementation.
Yes, using the params keyword. The arguments are specified as a list of arguments of a specific type, e.g. int. For ultimate flexibility, the type can be object. The standard example of a method which uses this approach is System.Console.WriteLine().
Yes, an interface can inherit from another interface. It is possible for a class to inherit an interface multiple times, through base classes or interfaces it inherits. In this case, the class can only implement the interface one time, if it is declared as part of the new class. If the inherited interface is not declared as part of the new class, its implementation is provided by the base class that declared it. It is possible for a base class to implement interface members using virtual members; in that case, the class inheriting the interface can change the interface behavior by overriding the virtual members.
- When working on large projects, spreading a class over separate files enables multiple programmers to work on it at the same time.
- When working with automatically generated source, code can be added to the class without having to recreate the source file. Visual Studio uses this approach when it creates Windows Forms, Web service wrapper code, and so on. You can create code that uses these classes without having to modify the file created by Visual Studio.
Yes, it possible to force garbage collector to run by calling the Collect() method, but this is not considered a good practice because this might create a performance over head. Usually the programmer has no control over when the garbage collector runs. The garbage collector checks for objects that are no longer being used by the application. If it considers an object eligible for destruction, it calls the destructor(if there is one) and reclaims the memory used to store the object.
If the application is using expensive external resource, it is recommend to explicitly release the resource before the garbage collector runs and frees the object. We can do this by implementing the Dispose method from the IDisposable interface that performs the necessary cleanup for the object. This can considerably improve the performance of the application.
Yes, even though Structs are not reference types, structs can have constructors.
- A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
- Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.
No, User-defined types including classes, structs, and arrays, cannot be const. Only the C# built-in types excluding System.Object may be declared as const. Use the readonly modifier to create a class, struct, or array that is initialized one time at runtime (for example in a constructor) and thereafter cannot be changed.
Instance fields are specific to an instance of a type. If you have a class T, with an instance field F, you can create two objects of type T, and modify the value of F in each object without affecting the value in the other object.
The protected internal access means protected OR internal, not protected AND internal. In simple terms, a protected internal member is accessible from any class in the same assembly, including derived classes. To limit accessibility to only derived classes in the same assembly, declare the class itself internal, and declare its members as protected.
- Value types are stored on the stack where as reference types are stored on the managed heap.
- Value type variables directly contain their values where as reference variables holds only a reference to the location of the object that is created on the managed heap.
- There is no heap allocation or garbage collection overhead for value-type variables. As reference types are stored on the managed heap, they have the over head of object allocation and garbage collection.
- Value Types cannot inherit from another class or struct. Value types can only inherit from interfaces. Reference types can inherit from another class or interface.
Converting a reference type to a value type is called unboxing.
Boxing is used to store value types in the garbage-collected heap. Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Boxing a value type allocates an object instance on the heap and copies the value into the new object. Due to this boxing and unboxing can have performance impact.
String objects are immutable: they cannot be changed after they have been created. All of the String methods and C# operators that appear to modify a string actually return the results in a new string object. In the following example, when the contents of s1 and s2 are concatenated to form a single string, the two original strings are unmodified. The += operator creates a new string that contains the combined contents. That new object is assigned to the variable s1, and the original object that was assigned to s1 is released for garbage collection because no other variable holds a reference to it.
No, You can’t Serialize Hash table.Because, the .NET Framework does not allow serialization of any object that implements the IDictionary interface
Extension methods enables you to add new capabilities to an existing type. You don’t need to make any modifications to the existing type, just bring the extension method into scope and you can call it like a regular instance method. Extension methods need to be declared in a nongeneric, non-nested, static class.
Dynamic types are similar to object types except that type checking for object type variables takes place at compile time, whereas that for the dynamic type variables takes place at run time.
This question will be reasonably simple for a C# user with any amount of experience. It offers a baseline understanding of the candidate's experience with C#. What to look for:
- Clear understanding of when and how C# is used
- Ability to articulate several basic advantages of C#
- Knowledge of several important features of C#
Example: "One of the primary advantages of C# is that it is easy to learn. Other advantages include the fact that it is component oriented, object-oriented and part of .NET framework. Some of the features I find myself using most often are constructors and destructors, passing parameters, XML documentation and indexers."
In general, When we create object of a class, its reference is stored in stack memory and object is stored in heap and address of object is assigned to class reference.
No, structs do not support inheritance, but they can implement interfaces.
A class is used to model more complex behavior, or data that is intended to be modified after a class object is created. A struct is best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created.
It’s up to you to implement the method inside your own class, so implementation is left entirely up to you. This might cause a problem on a higher-level scale if similarly named methods from different interfaces expect different data, but as far as compiler cares you’re okay.
Yes, just place a colon, and then keyword base (parameter list to invoke the appropriate constructor) in the overloaded constructor definition inside the inherited class.
No. The access modifier on a property applies to both its get and set accessors. What you need to do if you want them to be different is make the property read-only (by only providing a get accessor) and create a private/internal set method that is separate from the property.
Private assembly is used inside an application only and does not have to be identified by a strong name. Shared assembly can be used by multiple applications and has to have a strong name.
Some security exceptions are thrown if you are working on a network share. There are some parts of the frameworks that will not run if being run off a share (roaming profile, mapped drives, etc.). To see if this is what's happening, just move the executable over to your local drive and see if it runs without the exceptions. One of the common exceptions thrown under these conditions is System.Security.SecurityException.
To get around this, you can change your security policy for the intranet zone, code group 1.2, (the zone that running off shared folders falls into) by using the caspol.exe tool.
No. However, there are plans for C# to support a type of template known as a generic. These generic types have similar syntax but are instantiated at run time as opposed to compile time.
No. C# does, however, support the concept of an indexer from language spec. An indexer is a member that enables an object to be indexed in the same way as an array. Whereas properties enable field-like access, indexers enable array-like access. As an example, consider the Stack class presented earlier. The designer of this class may want to expose array-like access so that it is possible to inspect or alter the items on the stack without performing unnecessary Push and Pop operations. That is, Stack is implemented as a linked list, but it also provides the convenience of array access.
Indexer declarations are similar to property declarations, with the main differences being that indexers are nameless (the name used in the declaration is this, since this is being indexed) and that indexers include indexing parameters. The indexing parameters are provided between square brackets.
In a garbage collected environment, it's impossible to get true determinism. However, a design pattern that we recommend is implementing IDisposable on any class that contains a critical resource. Whenever this class is consumed, it may be placed in a using statement.
C# requires only a single parameter for delegates: the method address. Unlike other languages, where the programmer must specify an object reference and the method to invoke, C# can infer both pieces of information by just specifying the method's name. For example, let's use System.Threading.ThreadStart: Foo MyFoo = new Foo(); ThreadStart del = new ThreadStart(MyFoo.Baz); This means that delegates can invoke static class methods and instance methods with the exact same syntax!
There are imperative and interrogative functions. Imperative functions are the one which return a value while the interrogative functions do not return a value.
A constructor is a special type of function/method which has the same name as its class. The constructor is invoked whenever an object of a class is created. It is called constructor since it constructs the values of the class data members.
The destructor is a special type member function/method which has the same name as its class name preceded by a tilde (~) sign. The destructor is used to release unmanaged resources allocated by the object. It is called automatically before an object is destroyed. It cannot be called explicitly. A class can have only one destructor.
Generics were introduced in C# 2.0. Generics allow you to define type-safe classes, interfaces, methods, events, delegates, and generic collections without compromising type safety, performance, or productivity. In generics, a generic type parameter is supplied between the open (<) and close (>) brackets and which makes it strongly typed collections i.e. generics collections contain only similar types of objects.
An inner exception can be described as a property of exception class which gives you a brief understanding of the exception, i.e., details on the parent exception as well as the child exception.
The difference between direct cast and ctype is that direct cast is used for the conversion of type of an object that requires the run time which is similar to the specified type in the direct cast. Whereas ctype is used for converting the conversion which is defined for the expression and the type.
The singleton design pattern is used in C# when the class has one instance and the access is provided globally.
A thread is defined as a set of instructions that are executed and which enables the program for performing concurrent processing. C# has just one thread and that is by default.
In C++, a struct and a class are pretty much the same thing. The only difference is the default visibility level (public for structs, private for classes). However, in C# structs and classes are very different. In C#, structs are value types (instances stored directly on the stack, or inline within heap-based objects), whereas classes are reference types (instances stored on the heap, accessed indirectly via a reference). Also structs cannot inherit from structs or classes, though they can implement interfaces. Structs cannot have destructors. A C# struct is much more like a C struct than a C++ struct.
No. They look the same but they are very different. The C# destructor syntax (with the familiar ~ character) is just syntactic sugar for an override of the System.Object Finalize method. This Finalize method is called by the garbage collector when it determines that an object is no longer referenced, before it frees the memory associated with the object. So far this sounds like a C++ destructor. The difference is that the garbage collector makes no guarantees about when this procedure happens. Indeed, the algorithm employed by the CLR garbage collector means that it may be a long time after the application has finished with the object. This lack of certainty is often termed 'non-deterministic finalization', and it means that C# destructors are not suitable for releasing scarce resources such as database connections, file handles etc.
To achieve deterministic destruction, a class must offer a method to be used for the purpose. The standard approach is for the class to implement the IDisposable interface. The user of the object must call the Dispose() method when it has finished with the object. C# offers the 'using' construct to make this easier.
Because different languages and environments have different calling conventions, different layout conventions, different sizes of primitives (cf. char in C# and char in C), different object creation/destruction conventions, and different design guidelines. You need a way to get the stuff out of managed land an into somewhere where unmanaged land can see and understand it and vice versa. That's what marshalling is for.
In C#, derived classes can inherit from one base class only. If you want to inherit from multiple base classes, use interface.
- Predicate: essentially Func
; asks the question "does the specified argument satisfy the condition represented by the delegate?" Used in things like List.FindAll.
- Action: Perform an action given the arguments. Very general purpose. Not used much in LINQ as it implies side-effects, basically.
- Func: Used extensively in LINQ, usually to transform the argument, e.g. by projecting a complex structure to one property.
Immutability (for strings or other types) can have numerous advantages:
- It makes it easier to reason about the code, since you can make assumptions about variables and arguments that you can't otherwise make.
- It simplifies multithreaded programming since reading from a type that cannot change is always safe to do concurrently.
- It allows for a reduction of memory usage by allowing identical values to be combined together and referenced from multiple locations. Both Java and C# perform string interning to reduce the memory cost of literal strings embedded in code.
- It simplifies the design and implementation of certain algorithms (such as those employing backtracking or value-space partitioning) because previously computed state can be reused later.
- Immutability is a foundational principle in many functional programming languages - it allows code to be viewed as a series of transformations from one representation to another, rather than a sequence of mutations.
Want to test this skill? Check out Adaface assessments
C# & SQL
C#, .NET & SQL
C# .NET Junior Developer
C# .NET Senior Developer Test
We evaluated several of their competitors and found Adaface to be the most compelling. Great default library of questions that are designed to test for fit rather than memorization of algorithms.