Array types
Arrays may be single-dimensional or multi-dimensional. Both “rectangular” and “jagged” arrays are supported.
Single-dimensional arrays are the most common type. The example
class Test
{
static void Main() {
int[] arr = new int[5];
for (int i = 0; i < arr.Length; i++)
arr[i] = i * i;
for (int i = 0; i < arr.Length; i++)
Console.WriteLine("arr[{0}] = {1}", i, arr[i]);
}
}
creates a single-dimensional array of int values, initializes the array elements, and then prints each of them out. The output produced is:
arr[0] = 0
arr[1] = 1
arr[2] = 4
arr[3] = 9
arr[4] = 16
The type int[] used in the previous example is an array type. Array types are written using a non-array-type followed by one or more rank specifiers. The example
class Test
{
static void Main() {
int[] a1; // single-dimensional array of int
int[,] a2; // 2-dimensional array of int
int[,,] a3; // 3-dimensional array of int
int[][] j2; // "jagged" array: array of (array of int)
int[][][] j3; // array of (array of (array of int))
}
}
shows a variety of local variable declarations that use array types with int as the element type.
Array types are reference types, and so the declaration of an array variable merely sets aside space for the reference to the array. Array instances are actually created via array initializers and array creation expressions. The example
class Test
{
static void Main() {
int[] a1 = new int[] {1, 2, 3};
int[,] a2 = new int[,] {{1, 2, 3}, {4, 5, 6}};
int[,,] a3 = new int[10, 20, 30];
int[][] j2 = new int[3][];
j2[0] = new int[] {1, 2, 3};
j2[1] = new int[] {1, 2, 3, 4, 5, 6};
j2[2] = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
}
}
shows a variety of array creation expressions. The variables a1, a2 and a3 denote rectangular arrays, and the variable j2 denotes a jagged array. It should be no surprise that these terms are based on the shapes of the arrays. Rectangular arrays always have a rectangular shape. Given the length of each dimension of the array, its rectangular shape is clear. For example, the lengths of a3’s three dimensions are 10, 20, and 30 respectively, and it is easy to see that this array contains 10*20*30 elements.
In contrast, the variable j2 denotes a “jagged” array, or an “array of arrays”. Specifically, j2 denotes an array of an array of int, or a single-dimensional array of type int[]. Each of these int[] variables can be initialized individually, and this allows the array to take on a jagged shape. The example gives each of the int[] arrays a different length. Specifically, the length of j2[0] is 3, the length of j2[1] is 6, and the length of j2[2] is 9.
The element type and shape of an array—including whether it is jagged or rectangular, and the number of dimensions it has—are part of its type. On the other hand, the size of the array—as represented by the length of each of its dimensions—is not part of an array’s type. This split is made clear in the language syntax, as the length of each dimension is specified in the array creation expression rather than in the array type. For instance the declaration
int[,,] a3 = new int[10, 20, 30];
has an array type of int[,,] and an array creation expression of new int[10, 20, 30].
For local variable and field declarations, a shorthand form is permitted so that it is not necessary to re-state the array type. For instance, the example
int[] a1 = new int[] {1, 2, 3};
can be shortened to
int[] a1 = {1, 2, 3};
without any change in program semantics.
The context in which an array initializer such as {1, 2, 3} is used determines the type of the array being initialized. The example
class Test
{
static void Main() {
short[] a = {1, 2, 3};
int[] b = {1, 2, 3};
long[] c = {1, 2, 3};
}
}
shows that the same array initializer syntax can be used for several different array types. Because context is required to determine the type of an array initializer, it is not possible to use an array initializer in an expression context without explicitly stating the type of the array.
Type system unification
C# provides a “unified type system”. All types—including value types—derive from the type object. It is possible to call object methods on any value, even values of “primitive” types such as int. The example
class Test
{
static void Main() {
Console.WriteLine(3.ToString());
}
}
calls the object-defined ToString method on an integer literal, resulting in the output “3”.
The example
class Test
{
static void Main() {
int i = 123;
object o = i; // boxing
int j = (int) o; // unboxing
}
}
is more interesting. An int value can be converted to object and back again to int. This example shows both boxing and unboxing. When a variable of a value type needs to be converted to a reference type, an object box is allocated to hold the value, and the value is copied into the box. Unboxing is just the opposite. When an object box is cast back to its original value type, the value is copied out of the box and into the appropriate storage location.
This type system unification provides value types with the benefits of object-ness without introducing unnecessary overhead. For programs that don’t need int values to act like objects, int values are simply 32-bit values. For programs that need int values to behave like objects, this capability is available on demand. This ability to treat value types as objects bridges the gap between value types and reference types that exists in most languages. For example, a Stack class can provide Push and Pop methods that take and return object values.
public class Stack
{
public object Pop() {...}
public void Push(object o) {...}
}
Because C# has a unified type system, the Stack class can be used with elements of any type, including value types like int
Arrays wih examples
Labels: Types and Objects
types with examples
Types
C# supports two kinds of types: value types and reference types. Value types include simple types (e.g., char, int, and float), enum types, and struct types. Reference types include class types, interface types, delegate types, and array types.
Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.
The example
class Class1
{
public int Value = 0;
}
class Test
{
static void Main() {
int val1 = 0;
int val2 = val1;
val2 = 123;
Class1 ref1 = new Class1();
Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
}
}
shows this difference. The output produced is
Values: 0, 123
Refs: 123, 123
The assignment to the local variable val1 does not impact the local variable val2 because both local variables are of a value type (the type int) and each local variable of a value type has its own storage. In contrast, the assignment ref2.Value = 123; affects the object that both ref1 and ref2 reference.
The lines
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
deserve further comment, as they demonstrate some of the string formatting behavior of Console.WriteLine, which takes a variable number of arguments. The first argument is a string, which may contain numbered placeholders like {0} and {1}. Each placeholder refers to a trailing argument with {0} referring to the second argument, {1} referring to the third argument, and so on. Before the output is sent to the console, each placeholder is replaced with the formatted value of its corresponding argument.
Developers can define new value types through enum and struct declarations, and can define new reference types via class, interface, and delegate declarations. The example
public enum Color
{
Red, Blue, Green
}
public struct Point
{
public int x, y;
}
public interface IBase
{
void F();
}
public interface IDerived: IBase
{
void G();
}
public class A
{
protected virtual void H() {
Console.WriteLine("A.H");
}
}
public class B: A, IDerived
{
public void F() {
Console.WriteLine("B.F, implementation of IDerived.F");
}
public void G() {
Console.WriteLine("B.G, implementation of IDerived.G");
}
override protected void H() {
Console.WriteLine("B.H, override of A.H");
}
}
public delegate void EmptyDelegate();
shows an example of each kind of type declaration. Later sections describe type declarations in detail.
Predefined types
C# provides a set of predefined types, most of which will be familiar to C and C++ developers.
The predefined reference types are object and string. The type object is the ultimate base type of all other types. The type string is used to represent Unicode string values. Values of type string are immutable.
The predefined value types include signed and unsigned integral types, floating point types, and the types bool, char, and decimal. The signed integral types are sbyte, short, int, and long; the unsigned integral types are byte, ushort, uint, and ulong; and the floating point types are float and double.
The bool type is used to represent boolean values: values that are either true or false. The inclusion of bool makes it easier to write self-documenting code, and also helps eliminate the all-too-common C++ coding error in which a developer mistakenly uses “=” when “==” should have been used. In C#, the example
int i = ...;
F(i);
if (i = 0) // Bug: the test should be (i == 0)
G();
results in a compile-time error because the expression i = 0 is of type int, and if statements require an expression of type bool.
The char type is used to represent Unicode characters. A variable of type char represents a single 16-bit Unicode character.
The decimal type is appropriate for calculations in which rounding errors caused by floating point representations are unacceptable. Common examples include financial calculations such as tax computations and currency conversions. The decimal type provides 28 significant digits.
The table below lists the predefined types, and shows how to write literal values for each of them.
Type Description Example
object The ultimate base type of all other types object o = null;
string String type;
a string is a sequence of Unicode characters
string s = "hello";
sbyte 8-bit signed integral type sbyte val = 12;
short 16-bit signed integral type short val = 12;
int 32-bit signed integral type int val = 12;
long 64-bit signed integral type long val1 = 12;
long val2 = 34L;
byte 8-bit unsigned integral type byte val1 = 12;
ushort 16-bit unsigned integral type ushort val1 = 12;
uint 32-bit unsigned integral type uint val1 = 12;
uint val2 = 34U;
ulong 64-bit unsigned integral type ulong val1 = 12;
ulong val2 = 34U;
ulong val3 = 56L;
ulong val4 = 78UL;
float Single-precision floating point type float val = 1.23F;
double Double-precision floating point type double val1 = 1.23;
double val2 = 4.56D;
bool Boolean type; a bool value is either true or false bool val1 = true;
bool val2 = false;
char Character type; a char value is a Unicode character char val = 'h';
decimal Precise decimal type with 28 significant digits decimal val = 1.23M;
Each of the predefined types is shorthand for a system-provided type. For example, the keyword int refers to the struct System.Int32. As a matter of style, use of the keyword is favored over use of the complete system type name.
Predefined value types such as int are treated specially in a few ways but are for the most part treated exactly like other structs. Operator overloading enables developers to define new struct types that behave much like the predefined value types. For instance, a Digit struct can support the same mathematical operations as the predefined integral types, and can define conversions between Digit and predefined types.
The predefined types employ operator overloading themselves. For example, the comparison operators == and != have different semantics for different predefined types:
Two expressions of type int are considered equal if they represent the same integer value.
Two expressions of type object are considered equal if both refer to the same object, or if both are null.
Two expressions of type string are considered equal if the string instances have identical lengths and identical characters in each character position, or if both are null.
The example
class Test
{
static void Main() {
string s = "Test";
string t = string.Copy(s);
Console.WriteLine(s == t);
Console.WriteLine((object)s == (object)t);
}
}
produces the output
True
False
because the first comparison compares two expressions of type string, and the second comparison compares two expressions of type object.
Conversions
The predefined types also have predefined conversions. For instance, conversions exist between the predefined types int and long. C# differentiates between two kinds of conversions: implicit conversions and explicit conversions. Implicit conversions are supplied for conversions that can safely be performed without careful scrutiny. For instance, the conversion from int to long is an implicit conversion. This conversion always succeeds, and never results in a loss of information. Implicit conversions can be performed implicitly, as shown in the example
class Test
{
static void Main() {
int intValue = 123;
long longValue = intValue;
Console.WriteLine("{0}, {1}", intValue, longValue);
}
}
which implicitly converts an int to a long.
In contrast, explicit conversions are performed with a cast expression. The example
class Test
{
static void Main() {
long longValue = Int64.MaxValue;
int intValue = (int) longValue;
Console.WriteLine("(int) {0} = {1}", longValue, intValue);
}
}
uses an explicit conversion to convert a long to an int. The output is:
(int) 9223372036854775807 = -1
because an overflow occurs. Cast expressions permit the use of both implicit and explicit conversions.
Labels: Types and Objects
Types,namespaces,GC
1. What’s the implicit name and type of the parameter that gets passed into the class’ set method?
Value, and it’s data type depends on whatever variable we’re changing.
2. How do you inherit from a class in C#?
Place a colon and then the name of the base class. Notice that it’s double colon in C++.
3. Does C# support multiple inheritance?
No, use interfaces instead.
4. When you inherit a protected class-level variable, who is it available to?
Classes in the same namespace.
5. Are private class-level variables inherited?
Yes, but they are not accessible, so looking at it you can honestly say that they are not inherited. But they are.
6. Describe the accessibility modifier protected internal. It’s available to derived classes and classes within the same Assembly (and naturally from the base class it’s declared in).
7. C# provides a default constructor for me. I write a constructor that akes a string as a parameter, but want to keep the no parameter one. How many constructors should I write?
Two. Once you write at least one constructor, C# cancels the freebie constructor, and now you have to write one yourself, even if there’s no implementation in it.
8. What’s the top .NET class that everything is derived from? System.Object .
9. How’s method overriding different from overloading?
When overriding, you change the method behavior for a derived class. Overloading simply involves having a method with the same name within the class.
10. What does the keyword virtual mean in the method definition? The method can be over-ridden.
11. Can you declare the override method static while the original method is non-static?
No, you can’t, the signature of the virtual method must remain the same, only the keyword virtual is changed to keyword override.
12. Can you override private virtual methods?
No, moreover, you cannot access private methods in inherited classes, have to be protected in the base class to allow any sort of access.
13. Can you prevent your class from being inherited and becoming a base class for some other classes?
Yes, that’s what keyword sealed in the class definition is for. The developer trying to derive from your class will get a message: cannot inherit from Sealed class WhateverBaseClassName. It’s the same concept as final class in Java.
14. Can you allow class to be inherited, but prevent the method from being over-ridden?
Yes, just leave the class public and make the method sealed.
15. What’s an abstract class?
A class that cannot be instantiated.A concept in C++ known as pure virtual method. A class that must be inherited and have the methods over-ridden. Essentially, it’s a blueprint for a class without any implementation.
16. When do you absolutely have to declare a class as abstract (as opposed to free-willed educated choice or decision based on UML diagram)?
When at least one of the methods in the class is abstract. When the class itself is inherited from an abstract class, but not all base abstract methods have been over-ridden.
17. What’s an interface class? It’s an abstract class with public abstract methods all of which must be implemented in the inherited classes.
18. Why can’t you specify the accessibility modifier for methods inside the interface?
They all must be public. Therefore, to prevent you from getting the false impression that you have any freedom of choice, you are not allowed to specify any accessibility, it’s public by default.
19. Can you inherit multiple interfaces?
Yes, why not.
20. And if they have conflicting method names?
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.
21. What’s the difference between an interface and abstract class?
In the interface all methods must be abstract, in the abstract class some methods can be concrete. In the interface no accessibility modifiers are allowed, which is ok in abstract classes.
22. How can you overload a method?
Different parameter data types, different number of parameters, different order of parameters.
23. If a base class has a bunch of overloaded constructors, and an inherited class has another bunch of overloaded constructors, can you enforce a call from an inherited constructor to an arbitrary base constructor?
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.
24. What’s the difference between System. String and System.StringBuilder classes?
System. String is immutable; System.StringBuilder was designed with the purpose of having a mutable string where a variety of operations can be performed
25. How big is the data type int in .NET?
32 bits.
26. How big is the char?
16 bits (Unicode).
27. How do you initiate a string without escaping each backslash? Put an @ sign in front of the double-quoted string.
28. What are valid signatures for the Main function? public static void Main () public static int Main () public static void Main ( string[] args ) public static int Main (string[] args )
29. How do you initialize a two-dimensional array that you don’t know the dimensions of? int [ , ] myArray; //declaration myArray = new int [5, 8]; //actual initialization
30. What’s the access level of the visibility type internal? Current application.
31. What’s the difference between struct and class in C#? Structs cannot be inherited. Structs are passed by value, not by reference. Struct is stored on the stack, not the heap.
32. Explain encapsulation. The implementation is hidden, the interface is exposed.
33. What data type should you use if you want an 8-bit value that’s signed? sbyte .
34. Speaking of Boolean data types, what’s different between C# and /C++? There’s no conversion between 0 and false, as well as any other number and true, like in C/C++.
35. Where are the value-type variables allocated in the computer RAM? Stack.
36. Where do the reference-type variables go in the RAM? The references go on the stack, while the objects themselves go on the heap.
37. What is the difference between the value-type variables and reference-type variables in terms of garbage collection? The value-type variables are not garbage-collected, they just fall off the stack when they fall out of scope, the reference-type objects are picked up by GC when their references go null.
38How do you convert a string into an integer in .NET? Int32.Parse( string)
39How do you box a primitive data type variable? Assign it to the object, pass an object.
40Why do you need to box a primitive variable?
To pass it by reference.
41What’s the difference between Java and .NET garbage collectors?
Sun left the implementation of a specific garbage collector up to the JRE developer, so their performance varies widely, depending on whose JRE you’re using. Microsoft standardized on their garbage collection.
42How do you enforce garbage collection in .NET? System.GC.Collect ( );
43.an you declare a C++ type destructor in C# like ~MyClass ()?
Yes, but what’s the point, since it will call Finalize(), and Finalize() has no guarantees when the memory will be cleaned up, plus, it introduces additional load on the garbage collector.
44What’s different about namespace declaration when comparing that to package declaration in Java?
No semicolon.
45What’s the difference between const and read only?
You can initialize read only variables to some runtime values. Let’s say your program uses current date and time as one of the values that won’t change. This way you declare public read only string DateT = new DateTime ().ToString ().
46\a character do?
On most systems, produces a rather annoying beep.
47. Can you create enumerated data types in C#?
Yes.
48. What’s different about switch statements in C#?
No fall-throughs allowed.
49. What happens when you encounter a continue statement inside the for loop?
The code for the rest of the loop is ignored; the control is transferred back to the beginning of the loop.
50. Is goto statement supported in C#? How about Java?
Gotos are supported in C# to the fullest. In Java goto is a reserved keyword that provides absolutely no functionality.
Labels: Types and Objects