[.net] Useful/obscure .Net classes

Started by
20 comments, last by mutex 17 years ago
Some of these are hints and tricks.. but still good to know :-)


Not a class but syntax:


have you ever done this?

if (myString != null)
return myString;
else
return "Empty";

well.. how about:

return myString ?? "Empty";

Both are equivalent [wink]



System.BitConverter and System.Buffer are very useful for bit/byte manipulation.



Need memcpy? Marshal.Copy().



A lot of operators work on integers by default, ie 1 << 15 will be integer. However so will 1 << 42. This will actually be the same as 1 << 10. However 1L << 42 will be fine. Bytes always get converted to integer when doing bitwise operations on them.



unchecked and checked blocks:

checked
{
byte b = 255;
b++; // exception, overflow
}

can also be used in an equation:

int z = checked(b+100);


There is a very subtle issue with floating point byte conversions.
If you have a float array, and want to manually set a value in that array (as 4 bytes) - eg, you are dumping byte RGBA colours into a float array..
BitConverter.ToSingle() won't work... In the event the bytes are X Y Z 255, the resulting float is NaN, which automatically gets converted to X Y 240 255 (iirc). The way to get around it is by using Buffer.BlockCopy() to copy an array with the 4 bytes into the float array. This one took a while to track down.



For threading, AutoResetEvents and ManualResetEvents are awesome.
As are ReadWriteLocks.
If you have a large number of tasks running, and you want to react when one finishes, you can do:

WaitHandle[] handles = {threadOneCompletedTaskEvent,threadTwoCom.... };

while (tasksToDo)
threads[WaitHandle.WaitAny(handles)].AssignNextTask(...);

Each handle will be an AutoResetEvent in this case.
There will be another autoreset event that signals the worker to start up again (set in AssignNextTask). Use WaitHandle.SignalAndWait(..,..); when a task finishs.


Never have ushort,ubyte,uint or ulong as parametres for public methods. Unless:
you have them as an overload with the following attribute:
[CLSCompliant(false)]



Self managed events...
What may not be obvious is that a Property can be an event too... This is *really* useful for roll-your-own events.

public event MyEventHandler MyEvent
{
add {}
remove {}
}



AppDomain.CurrentDomain has some very useful events.

such as:

AppDomain.CurrentDomain.AssemblyResolve
If .net can't find an assembly you reference, it will call this event (instead of crashing). You can load it manually with Assembly.Load() here if you want (say, from a .zip file - to keep your app nice and small)

AppDomain.CurrentDomain.UnhandledException
Should be obvious :-) - although use it as a last resort



Assembly.Load(byte[]) does not correctly load assembly evidence, however Assembly.ReflectionOnlyLoad(byte[]) does. So you can call Assembly.ReflectionOnlyLoad, then use the evidence in Assembly.Load(byte[],assembly.Evidence,...)




Sometimes, you want to scan all the .dll files your application has, and find all classes implementing an interface (or class, etc). Eg you might have an editor, and it wants to know what entities it can let you add.
Here is how to do it:

Store the interface/class that you want to scan for in it's own assembly.

This should probably be *recursive*

foreach (AssemblyName an in current_assembly.GetReferencedAssemblies()){  Assembly assembly = Assembly.ReflectionOnlyLoad(an.FullName);  if (assembly.GetReferencedAssemblies().Contains(interface_assembly_name))  {     assembly = Assembly.Load(an.FullName);     foreach (Type t in assembly.GetExportedTypes())     {        if (interface_type.IsAssignableFrom(t))            types.Add(t);     }  }}


This will be *MUCH* faster than loading every .dll in the directory, or similar operations.




When using XML classes, eg XmlElement, do not use SelectNodes() or SelectSingleNode(), as these use xpath (I think). Use GetElementsByTagName().



Want to confuse someone? Have a Queue filled with delegates:

if (taskQueue.Count > 0)
taskQueue.Dequeue()();



System.Array has loads of useful static methods. Such as Array.Resize() [wink]


System.Activator can be used to create objects from a type. You can also do this by using reflection to get the ConstructorInfo of a Constructor on a type.
This can even be done for remote objects over the web.


System.Environment contains loads of stuff.




there are of course loads and loads more. I'm just browsing some of my code and picking out interesting things.

[Edited by - RipTorn on March 25, 2007 11:42:10 AM]
Advertisement
DynamicMethod and SecureString come to mind.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by RipTorn
return myString ?? "Empty";


Wow! I've read the whole spec, tons of tutorials etc, but I've missed that one!! thanks a lot!!
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

That SecureString is nice to know. System.Environment and the stuff in Diagnostics (like StackTrace) is useful. XML, serialization, threading and network are useful but not terribly obscure.

StringBuilder is good to know and subtle in its benefits.

Generic delegates are fairly useful in cutting down cookie cutter typing.

implicit coversion operators help cut down typing a bit with functors:

class SomeEventTosser{    public delegate void EventType(SomeEventTosser src);    public event EventType OnEvent;}class SomeEventFunctor{    // params    public void MainMethod(){        // use params to handle incoming event.    }     public static implicit operator SomeEventTosser.EventType( SomeEventFunctor rhs){         return( rhs.MainMethod );    }}// Allows:SomeEventTosser  foo = new SomeEventTosser();foo.OnEvent += new SomeEventFunctor( /* params */ );


Allows for a little more curt syntax while still being pretty descriptive. And remember even being subscribed to an event will keep an object alive, so in the above scenario the functor still stick around as long as the event does.
Some very interesting stuff in this thread!

System.Reflection is great, although it can get a bit slow if you go overboard on it. Hashtables are also very useful, and I second the nomination of the StringBuilder too.
Indeed, thank you to everyone for your suggestions. I've learned a ton too just reading the thread, let alone the stuff I've since MSDN'd.
Without order nothing can exist - without chaos nothing can evolve.
Quote:Original post by RipTorn


have you ever done this?

if (myString != null)
return myString;
else
return "Empty";

well.. how about:

return myString ?? "Empty";

Both are equivalent [wink]



I've never seen double ? syntax before, I'll have to look that one up. However, I guess from my C++ days I never use the first example, I always use tri state if, as well as using the built in Empty string:

return myString != null ? myString : string.Empty;

Another one I just found that is slightly different but very useful is:

bool string.IsNullOrEmpty(string value);


Quote:Original post by RipTorn

have you ever done this?

if (myString != null)
return myString;
else
return "Empty";

well.. how about:

return myString ?? "Empty";

Both are equivalent [wink]


Another usefull abbreviation is this:

int?    x;//short for:System.Nullable<int>   x;


Nullable Types (C# Programming Guide)
?? Operator (C# Reference)
How do I set my laser printer on stun?
You can 'foreach' through enums without having a "maximum" entry in the enum:

enum MyEnum{  A, B, C}void SomeFunc(){  MyEnum[] values = (MyEnum[])Enum.GetValues(MyEnum);    foreach (MyEnum foo in values)  {    // stuff here.  }}
http://www.codeplex.com/entlib

While not in the framework, Microsoft has a nice set of development libraries called Enterprise Library. It has a lot of functionality that people often write their own code for.

It's composed of 'blocks' for logging, exception handling, caching, security, data access, and others. Each of these blocks uses a separate section in app.config and can easily plug in to an existing system. A config editor is also supplied.

The Composite UI Block (CAB) provides much of the infrastructure for developing enterprise-scale applications. A Smart Client Software Factory (SCSF) package automates many CAB tasks such as generating code files and setting up VS projects. For small projects this is totally unnecessary.

A new version is due out at the beginning of April with a couple new blocks.

This topic is closed to new replies.

Advertisement