Faqs
Faqs
Faqs
.NET is a "revolutionary new platform, built on open Internet protocols and standards, with tools
and services that meld computing and communications in new ways".
A more practical definition would be that .NET is a new environment for developing and running
software applications, featuring ease of development of web-based services, rich standard run-
time services available to components written in a variety of programming languages, and inter-
language and inter-machine interoperability.
2. Basic terminology
3. Assemblies
3.3 What is the difference between a private assembly and a shared assembly?
• Location and visibility: A private assembly is normally used by a single application, and is
stored in the application's directory, or a sub-directory beneath. A shared assembly is
normally stored in the global assembly cache, which is a repository of assemblies
maintained by the .NET runtime. Shared assemblies are usually libraries of code which
many applications will find useful, e.g. the .NET framework classes.
• Versioning: The runtime enforces versioning constraints only on shared assemblies, not on
private assemblies.
4. Application Domains
5. Garbage Collection
5.2 Is it true that objects don't always get destroyed immediately when the last
reference goes away?
Yes. The garbage collector offers no guarantees about the time when an object will be
destroyed and its memory reclaimed.
5.3 Why doesn't the .NET runtime offer deterministic destruction?
Because of the garbage collection algorithm. The .NET garbage collector works by periodically
running through a list of all the objects that are currently being referenced by an application. All
the objects that it doesn't find during this search are ready to be destroyed and the memory
reclaimed. The implication of this algorithm is that the runtime doesn't get notified immediately
when the final reference on an object goes away - it only finds out during the next sweep of the
heap.
Futhermore, this type of algorithm works best by performing the garbage collection sweep as
rarely as possible. Normally heap exhaustion is the trigger for a collection sweep.
5.5 Does non-deterministic destruction affect the usage of COM objects from
managed code?
Yes. When using a COM object from managed code, you are effectively relying on the garbage
collector to call the final release on your object. If your COM object holds onto an expensive
resource which is only cleaned-up after the final release, you may need to provide a new
interface on your object which supports an explicit Dispose() method.
5.6 I've heard that Finalize methods should be avoided. Should I implement Finalize
on my class?
An object with a Finalize method is more work for the garbage collector than an object without
one. Also there are no guarantees about the order in which objects are Finalized, so there are
issues surrounding access to other objects from the Finalize method. Finally, there is no
guarantee that a Finalize method will get called on an object, so it should never be relied upon
to do clean-up of an object's resources.
Microsoft recommend the following pattern:
public class CTest : IDisposable
{
public void Dispose()
{
... // Cleanup activities
GC.SuppressFinalize(this);
}
5.8 How can I find out what the garbage collector is doing?
Lots of interesting statistics are exported from the .NET runtime via the '.NET CLR xxx'
performance counters. Use Performance Monitor to view them.
6. Serialization
6.2 Does the .NET Framework have in-built support for serialization?
There are two separate mechanisms provided by the .NET class library - XmlSerializer and
SoapFormatter/BinaryFormatter. Microsoft uses XmlSerializer for Web Services, and uses
SoapFormatter/BinaryFormatter for remoting. Both are available for use in your own code.
7. Attributes
class CApp
{
public static void Main()
{
object[] atts = typeof(CTest).GetCustomAttributes(true);
Code Groups:
8.7 I'm having some trouble with CAS. How can I diagnose my problem?
Caspol has a couple of options that might help. First, you can ask caspol to tell you what code
group an assembly belongs to, using caspol -rsg. Similarly, you can ask what permissions are
being applied to a particular assembly using caspol -rsp.
8.8 I can't be bothered with all this CAS stuff. Can I turn it off?
Yes, as long as you are an administrator. Just run:
caspol -s off
using System;
namespace AndyMc
{
public class CSharpCOMServer
{
public CSharpCOMServer() {}
public void SetName( string name ) { m_name = name; }
public string GetName() { return m_name; }
private string m_name;
}
}
Then compile the .cs file as follows:
csc /target:library testcomserver.cs
You should get a dll, which you register like this:
regasm testcomserver.dll /tlb:testcomserver.tlb /codebase
Now you need to create a client to test your .NET COM component. VBScript will do - put the
following in a file called comclient.vbs:
Dim dotNetObj
Set dotNetObj = CreateObject("AndyMc.CSharpCOMServer")
dotNetObj.SetName ("bob")
MsgBox "Name is " & dotNetObj.GetName()
and run the script like this:
wscript comclient.vbs
And hey presto you should get a message box displayed with the text "Name is bob".
11. Miscellaneous
• Singleton. All incoming requests from clients are processed by a single server object.
• Client-activated object. This is the old stateful (D)COM model whereby the client receives a
reference to the remote object and holds that reference (thus keeping the remote object
alive) until it is finished with it.
Distributed garbage collection of objects is managed by a system called 'leased based lifetime'.
Each object has a lease time, and when that time expires the object is disconnected from the
.NET runtime remoting infrastructure. Objects have a default renew time - the lease is renewed
when a successful call is made from the client to the object. The client can also explicitly renew
the lease.
11.2 How can I get at the Win32 API from a .NET program?
Use P/Invoke. This uses similar technology to COM Interop, but is used to access static DLL
entry points instead of COM objects. Here is an example of C# calling the Win32 MessageBox
function:
using System;
using System.Runtime.InteropServices;
class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox",
SetLastError=true, CharSet=CharSet.Auto)]
public static extern int MessageBox(int hWnd, String strMessage,
String strCaption, uint uiType);
12.3 Internet
12.4 XML
while( reader.Read() )
{
if( reader.NodeType == XmlNodeType.Element && reader.Name ==
"PERSON" )
{
reader.Read(); // Skip to the child text
Console.WriteLine( reader.Value );
}
}
12.5 Threading
m_thread.Start();
}
// ThreadMain() is executed on the new thread.
private void ThreadMain()
{
Console.WriteLine( m_data );
}
12.6 Tracing
12.6.1 Is there built-in support for tracing/logging?
Yes, in the System.Diagnostics namespace. There are two main classes that deal with tracing -
Debug and Trace. They both work in a similar way - the difference is that tracing from the Debug
class only works in builds that have the DEBUG symbol defined, whereas tracing from the Trace
class only works in builds that have the TRACE symbol defined. Typically this means that you
should use System.Diagnostics.Trace.WriteLine for tracing that you want to work in debug and
release builds, and System.Diagnostics.Debug.WriteLine for tracing that you want to work only
in debug builds.
1. Introduction
2. Basic types
2.2 Is it true that all C# types derive from a common base class?
Yes and no. All types can be treated as if they derive from object (System.Object), but in order
to treat an instance of a value type (e.g. int, float) as object-derived, the instance must be
converted to a reference type using a process called 'boxing'. In theory a developer can forget
about this and let the run-time worry about when the conversion is necessary, but in reality this
implicit conversion can have side-effects that may trip up the unwary.
2.3 So this means I can pass an instance of a value type to a method that takes an
object as a parameter?
Yes. For example:
class CApplication
{
public static void Main()
{
int x = 25;
string s = "fred";
DisplayMe( x );
DisplayMe( s );
}
2.4 What are the fundamental differences between value types and reference types?
C# divides types into two categories - value types and reference types. Most of the basic
intrinsic types (e.g. int, char) are value types. Structs are also value types. Reference types
include classes, interfaces, arrays and strings. The basic idea is straightforward - an instance of
a value type represents the actual data (stored on the stack), whereas an instance of a
reference type represents a pointer or reference to the data (stored on the heap).
int x1 = 3; // x1 is a value on the stack
int x2 = new int();
x2 = 3; // x2 is also a value on the stack!
2.5 Okay, so an int is a value type, and a class is a reference type. How can int be
derived from object?
It isn't, really. When an int is being used as an int, it is a value (on the stack). However, when it
is being used as an object, it is a reference to an integer value on the heap. In other words,
when you treat an int as an object, the runtime automatically converts the int value to an object
reference. This process is called boxing. The conversion involves copying the contents of the int
from the stack to the heap, and creating an object instance which refers to it. Unboxing is the
reverse process - the object is converted back to a stack-based value.
int x = 3; // new int value 3 on the stack
object objx = x; // new int on heap, set to value 3 - still have x=3 on stack
int y = (int)objx; // new value 3 on stack, still got x=3 on stack and objx=3
on heap
3.1 Structs are largely redundant in C++. Why does C# have them?
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 (stored on the stack), whereas classes are
reference types (stored on the heap). Also structs cannot inherit from structs or classes, though
they can implement interfaces. Structs cannot have destructors.
4. Exceptions
class CApp
{
public static void Main()
{
string s = "fred";
long i = 10;
class CTest
{
class CApp
{
public static void Main()
{
long i = 10;
CTest ctest = new CTest();
DisplayTypeInfo( ctest );
DisplayTypeInfo( i );
}
class CAmerican
{
public void BePatriotic()
{
Console.WriteLine( "... <gulp> ... God bless America.");
}
}
class CBrit
{
public void BeXenophobic()
{
Console.WriteLine( "Bloody foreigners ... " );
}
}
class CApplication
{
public static void RevealYourStereotype( Stereotype[] stereotypes )
{
foreach( Stereotype s in stereotypes )
s();
}
// Reveal yourselves!
RevealYourStereotype(stereotypes );
}
}
This produces the following result:
... <gulp>... God bless America.
Bloody foreigners ...
8. Miscellaneous
8.2 I've seen some string literals which use the @ symbol, and some which don't.
What's that all about?
The @ symbol before a string literal means that escape sequences are ignored. This is
particularly useful for file names, e.g.
string fileName = "c:\\temp\\test.txt"
versus:
string fileName = @"c:\temp\test.txt"
class CApp
{
public static void Main( string[] args )
{
Console.WriteLine( "You passed the following
arguments:" );
foreach( string arg in args )
Console.WriteLine( arg );
}
}