string
is an alias in C# for System.String
.
So technically, there is no difference. It's like int
vs. System.Int32
.
As far as guidelines, it's generally recommended to use string
any time you're referring to an object.
e.g.
string place = "world";
Likewise, I think it's generally recommended to use String
if you need to refer specifically to the class.
e.g.
string greet = String.Format("Hello {0}!", place);
This is the style that Microsoft tends to use in their examples.
It appears that the guidance in this area may have changed, as StyleCop now enforces the use of the C# specific aliases.
In .NET, there are two categories of types, reference types and value types.
Structs are value types and classes are reference types.
The general difference is that a reference type lives on the heap, and a value type lives inline, that is, wherever it is your variable or field is defined.
A variable containing a value type contains the entire value type value. For a struct, that means that the variable contains the entire struct, with all its fields.
A variable containing a reference type contains a pointer, or a reference to somewhere else in memory where the actual value resides.
This has one benefit, to begin with:
- value types always contains a value
- reference types can contain a null-reference, meaning that they don't refer to anything at all at the moment
Internally, reference types are implemented as pointers, and knowing that, and knowing how variable assignment works, there are other behavioral patterns:
- copying the contents of a value type variable into another variable, copies the entire contents into the new variable, making the two distinct. In other words, after the copy, changes to one won't affect the other
- copying the contents of a reference type variable into another variable, copies the reference, which means you now have two references to the same somewhere else storage of the actual data. In other words, after the copy, changing the data in one reference will appear to affect the other as well, but only because you're really just looking at the same data both places
When you declare variables or fields, here's how the two types differ:
- variable: value type lives on the stack, reference type lives on the stack as a pointer to somewhere in heap memory where the actual memory lives (though note Eric Lipperts article series: The Stack Is An Implementation Detail.)
- class/struct-field: value type lives completely inside the type, reference type lives inside the type as a pointer to somewhere in heap memory where the actual memory lives.
Best Answer
To add a little to Brian's answer, and your comment/question:
The difference between a Managed/Unmanaged resource is that the Garbage Collector is aware of managed resources and isn't aware of unmanaged resources. I know that answer isn't very concrete but the difference is huge.
To help draw the line in the sand here is the short (and probably riddled with little errors) version of how GC runs and cleans up memory:
The garbage collector is aware of all managed objects but when garbage collection runs it doesn't initially know if any given object is still in use or is elegible to be released. It determines whether or not it can cleanup an object by initially marking all objects as garbage, then traversing from the application root to all referenced objects. Each object that has a relationship back to the root (a reference, either direct or indirect) gets marked as reachable and is no longer considered garbage. After the GC runs through every reachable object it cleans up the rest since they are no longer in use.
In almost all cases working with .NET framework objects you can be assured that objects are managed (.NET provides managed wrappers of nearly all unmanaged resources to ensure they are properly cleaned up); other third party components which hook into the Win32 API (or your components which do this) are the objects which may be cause for concern.
There are some .NET objects which can be considered to be somewhat unmanaged. Components of the Graphics library are one example.
Most ".NET Memory leaks" aren't really memory leaks in the true sense. Typically they occur when you think you have removed an object from use but in fact the object still has some reference to the application. A common example is adding eventhandlers (obj.SomeEvent += OnSomeEvent -or- AddHandler obj.SomeEvent, AddressOf OnSomeEvent) and not removing them.
These 'lingering references' are technically not memory leaks since your application is still technically using them; however if there are enough of them your application can suffer severe performance impacts and may show signs of resource issues (OutOfMemoryExceptions, unable to attain window handles, etc).
I'm an intermediate .NET developer and unfortunately know about these problems first-hand. I recommend playing with ANTS Profiler to help become familiar with lingering references (there is a free trial version) or if you want to get a little bit more nitty-gritty research using WinDbg and SOS.DLL to look at the managed heap. If you decide to look into the latter I recommend reading Tess Ferrandez' blog; she has a lot of great tutorials and advice on using Windbg effectively