|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
Download DotNetQuizSamples.zip - 253.11 KB
Introductionsoftware architects invites you to prove your knowledge about certain subjects concerning Microsoft .NET technology by participating in a monthly quiz. This month the quiz is about C# and .NET secrets. In this article you can reread the questions. Additionally you get background information about the correct answers. You haven't participated in the quiz yet? Try it first and come back to read about the answers later! Here is a list of all questions included in the quiz. Use the hyperlinks to jump to the topic you are interested in:
Question 1 - A Simple One To StartThe CTS (Common Type System) does not know about object orientation at all. Programming languages like C# include all the OO logic. They generate procedural IL code behind the scenes. True or false? That's absolutely not true! The Common Type System supports object oriented and procedural languages. It has support for OO constructs built in. If you are interested you can download the ECMA C# and Common Language Infrastructure Standards from Microsoft's website. The documents include a good introduction into as well as a detailed documentation of the Common Type System. Question 2 - String vs. System.StringWhat is more efficient in respect of memory usage and performance: The use of string or the use of System.String? The correct answer is It doesn’t matter which one you take, they perform equally. You can prove that the C# compiler and the .NET CLR treats Mark the use of auto-implemented properties in this sample. This is a new feature of C# 3.0! internal class PersonString
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
public PersonString(string FirstName, string LastName)
{
this.FirstName = FirstName;
this.LastName = LastName;
}
public void Replace( string TextToFind, string ReplacingText )
{
FirstName = FirstName.Replace( TextToFind, ReplacingText );
LastName = LastName.Replace( TextToFind, ReplacingText );
}
public override string ToString()
{
return FirstName + " " + LastName;
}
}
internal class PersonSystemString
{
public System.String FirstName { get; private set; }
public System.String LastName { get; private set; }
public PersonSystemString(System.String FirstName,
System.String LastName)
{
this.FirstName = FirstName;
this.LastName = LastName;
}
public void Replace(System.String TextToFind,
System.String ReplacingText)
{
FirstName = FirstName.Replace(TextToFind, ReplacingText);
LastName = LastName.Replace(TextToFind, ReplacingText);
}
public override System.String ToString()
{
return FirstName + " " + LastName;
}
}
The implementation of Main uses implicitly typed variables. This is a new featur of C# 3.0! See question 2 for more details about implicitly typed variables. static class Program
{
static void Main()
{
var pString = new PersonString("Rainer", "Stropek");
System.Console.WriteLine(pString);
var pSystemString = new PersonSystemString("Rainer", "Stropek");
System.Console.WriteLine(pSystemString);
}
}
After compiling the program we can use ILDASM (MS Intermediate Language Disassembler) to generate a readable version of the IL: ildasm.exe /output="$(TargetDir)\$(TargetName).il" $(TargetPath) If you compare the IL of the two classes you can see that they are (with the exception of their names) absolutely identical. Question 3 - Implicitly Typed VariablesC# 3.0 introduces implicitly typed local variables. You do not need to specify a type for a local variable any more! The compiler figures out which type to use for you. So what do you think; does the following code work? namespace ImplicitTypes
{
class Program
{
static void Main()
{
var v = "Hello World!";
v = 10;
System.Console.WriteLine(v);
}
}
}
The correct answer is No, you cannot compile this code. The code does not compile. The line You can read more about implicitly typed local variables in MSDN. Question 4 - Value vs. Reference TypesWhat is the output of the following program? namespace ValueVsReferenceTypes
{
class Program
{
static void Main()
{
var stringValue = "Hello World!";
var stringValue2 = stringValue;
stringValue = "Hello Austria!";
System.Console.WriteLine(stringValue2);
var array = new[] { 1, 2, 3, 4 };
var array2 = array;
array[0] = 99;
System.Console.WriteLine(array2[0]);
}
}
}
The correct answer is Hello World! 99. Although
Question 5 - Finalizing ObjectsIt is a good practise to use destructors in C# just like in C++. Put cleanup code in your class' destructor and the CLR will care for the rest. Is that correct? The correct answer is Cleaning up in the destructor is fine. But that is not enough! C# knows destructors. A destructor is the same as a Take a look at the following program: using System;
using System.IO;
namespace Finalizers
{
internal class FileGenerator : IDisposable
{
public FileGenerator()
{
}
~FileGenerator()
{
// Just a debug output
Console.WriteLine("Closing file!");
}
public void Generate(int Length)
{
// Here some work is done...
}
public void Dispose()
{
// Just a debug output
Console.WriteLine("Disposing object!");
}
}
class Program
{
static void Generate()
{
using ( var fGen = new FileGenerator() )
fGen.Generate(512);
}
static void Main(string[] args)
{
Generate();
// Here we do some work; simulated by ReadLine statement
Console.Write("Please Press Enter...");
Console.ReadLine();
}
}
}
If you run this program you will notice that the output Closing file! appears at the very end of the program. The destructor is not immediately called when the object This is one of the reasons why a destructor or a finalizer is not enough for an object that has to clean up when it is no longer needed. Here is a list of things you should consider regarding cleanup:
Jeffrey Richter wrote an interesting article about memory management and finalization of objects in the MSDN Magazine. Although the text has been written in 2000 it is still worth reading! Question 6 - Lambda ExpressionsIn C# every method must have a name. True or false? That's not true! Since the version 2.0 C# has known anonymous methods. Take a look at the following code: namespace AnonymousMethods
{
class Program
{
delegate int CalcOperation(int x);
static int PerformCalculation( int x, CalcOperation calc )
{
return calc(x);
}
static void Main()
{
System.Console.Write(PerformCalculation(5,
delegate(int x) { return x * x; }));
}
}
}
The In C# 3.0 you can replace anonymous methods with Lamdba Expressions in most cases. In our case we could change the implementation of the static void Main()
{
System.Console.Write(PerformCalculation(5, x => x*x ));
}
If you take a look behind the scenes and check the intermediate language that the C# compiler generates you will see that the generated IL nearly does not differ between C# 2.0 anonymous methods and Lamdba Expressions. Question 7 - Nullable TypesWhat is the output of the following program? namespace NullableTypes
{
class Program
{
static void Main()
{
int a = 10;
int? b = 20;
int? c = null;
System.Console.WriteLine( a + c ?? b );
}
}
}
The correct answer is 20. In C# you can make every value type nullable by adding a question mark to the type's name (you could also use Question 8 - JIT CompilerThe JIT compiler converts the IL in a portable executable into native machine language... The correct answer is ...method by method. During loading the CLR creates a stub for each method in a type when it is loaded and initialized. When a method is called for the first time the stub passes control to the JIT compiler which converts the MSIL for that method into native code. If the method is called again the native code is executed without involving the JIT. You can observe how the JITter generates native code using the following code sample: namespace JIT
{
class Program
{
static void Method1()
{
System.Console.WriteLine("Method1");
}
static void Method2()
{
System.Console.WriteLine("Method2");
}
static void Main()
{
System.Console.ReadLine();
Method1();
System.Console.ReadLine();
Method2();
System.Console.ReadLine();
Method1();
System.Console.ReadLine();
}
}
}
In the Performance Monitor you can see how the JITter generates native code. If you do not want to convert your IL code method by method every time the program starts you can use the Native Image Generator (ngen.exe) to convert it e.g. during installation. ngen generates processor-specific machine code in the native image cache. The runtime uses these images from the cache instead of using the JIT compiler to compile the original assembly. Note: You cannot use
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||