What are your favorite lesser-known .NET Base Class Library classes and methods?
Path [1] class. I can't count the times the lack of its usage came up in code-reviews. People tend to go for the string concatenations and sub-stringage instead of using Path.Combine [2] and Path.GetFileNameWithoutExtension [3], among others.
[1] http://msdn.microsoft.com/en-us/library/system.io.path%28VS.90%29.aspxPath
as hidden... I've used it so many times already! And it was always there in the IO
namespace, the kind of thing you import everywhere. - Camilo Martin
Path.Combine
would be better and often more powerful. - Mark Hurd
System.Security.SecureString - More people should be aware of this if their program accepts passwords or passphrases, or stores credit card numbers in memory. SecureString values are stored encrypted (obfuscated, rather), but most importantly, they are never swapped to disk and can be disposed of immediately when you're done with them.
They're tricky to use because you can only build them one character at a time (to encourage you to build them by capturing keystrokes as the user types their password), and require three lines of code to recover and then wipe their plain text, but when used properly they can make a program more secure by avoiding the virtual-memory vulnerability.
// Make a SecureString
SecureString sPassphrase = new SecureString();
Console.WriteLine("Please enter your passphrase");
ConsoleKeyInfo input = Console.ReadKey(true);
while (input.Key != ConsoleKey.Enter)
{
Console.Write('*');
sPassphrase.AppendChar(input.KeyChar);
input = Console.ReadKey(true);
}
sPassphrase.MakeReadOnly();
// Recover plaintext from a SecureString
// Marshal is in the System.Runtime.InteropServices namespace
try {
IntPtr ptrPassphrase = Marshal.SecureStringToBSTR(sPassphrase);
string uPassphrase = Marshal.PtrToStringUni(ptrPassphrase);
// ... use the string ...
}
catch {
// error handling
}
finally {
Marshal.ZeroFreeBSTR(ptrPassphrase);
}
Edit: At the end of the example the SecureString is converted into a regular managed string, which makes it vulnerable again (be sure to use the try-catch-finally pattern to Zero the string after you're done with it). SecureString's use is in reducing the surface-area of attack by limiting the number of copies the Garbage Collector will make of the value, and reducing the likelihood of being written to the swap file.
The .Net framework is gaining more support for SecureStrings that help eliminate the need to decrypt it. The PasswordBox control in WPF stores its value in a SecureString, System.Diagnostics.ProcessStartInfo's Password property takes a SecureString, and so does the constructor for X509Certificate2. Some third party components are beginning to take it as native currency, too.
SecureString
is an IDisposable
and thus should be managebly disposed. - Shimmy
System.Diagnostics.DebuggerDisplay
When you're debugging, if the class is attributed, visual studio will display the information on mouse-over. It even allows you to put in properties of private fields, etc.
[System.Diagnostics.DebuggerDisplay("MyClass: ID={ID} Name={Name} ChildName={_child.Name}")]
Ref: msdn [1]
[1] http://msdn.microsoft.com/en-us/library/x810d419.aspxThis saves a lot of typing on strings:
string.IsNullOrEmpty()
and
string.IsNullOrWhiteSpace() // .NET 4 only
Also a hidden gem using events; when declaring an event, a nice way to make sure you never need to check if it's null, is by initializing it to an empty anonymous delegate at declaration time:
public event EventHandler MyASimpleEvent = delegate {};
A cool way to log the name of the current method you're in:
string myMethodName = MethodBase.GetCurrentMethod().Name;
Console.WriteLine(myMethodName);
Getting the list of countries. Useful for populating the drop down box.
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures & ~CultureTypes.NeutralCultures
{
RegionInfo ri = new RegionInfo(ci.LCID);
Console.WriteLine(ri.EnglishName);
}
ref: http://jdconley.com/blog/archive/2007/09/05/list-of-country-names.aspx#1
RegionInfo
statement. - Timwi
System.Diagnostics.ConditionalAttribute. It makes the compiler ignore methods or classes that should only be active in certain build profiles. EG:
[Conditional("DEBUG")]
private void DumpProperties()
{
foreach (PropertyInfo prop in this.GetType().GetProperties())
Console.WriteLine(prop.GetValue(this, null));
}
Method(i++)
and the method is marked [Conditional("DEBUG")]
, then the i++
will be evaluated only in DEBUG mode, i.e. the variable i
will have a different value depending on whether you’re in debug or release mode... - Timwi
Most definitely String.Join(char separator, string[] list)
to create "a,b,c"
from {"a","b","c"
}. This alleviates keeping track of a boolean to check whether the first item is already used.
Use the
System.Diagnostics.Stopwatch
[1]
Don't do StartTime with DateTime, and then EndTime with DateTime.
See this answer [2].
[1] http://msdn2.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspxDateTime.Now
in situations where performance is a concern then it's good to be aware of DateTime.UtcNow
which is faster (it doesn't need to calculate local time) - STW
Using System.Environment.NewLine
instead of "\r\n".
System.Data.Common.DbConnectionStringBuilder
and
System.Data.SqlClient.SqlConnectionStringBuilder
These allow you to build a connection string in a programmatic way without have to remember the specific syntax.
Documentation: DbConnectionStringBuilder on MSDN [1]
[1] http://msdn.microsoft.com/en-us/library/system.data.common.dbconnectionstringbuilder.aspxSystem.Collections.ObjectModel.ObservableCollection<T>
Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
TextRenderer.MeasureText() is great for figuring out how large to draw your text. So often I see:
// this == something derived from Control
Size size;
using(Graphics g = this.CreateGraphics())
size = g.MeasureString(this.Text, this.Font).ToSize();
When really all you need is:
Size size = TextRenderer.MeasureText(this.Text, this.Font);
The former is how you did it in 1.0 and 1.1; the latter is how you do it in 2.0+. It's much cleaner, doesn't requiring creating an object which must be disposed, and doesn't leave you open to accidentally not disposing of a resource. Plus if you use TextRenderer.DrawText() your text will look better and localize better [1]. This stuff just plain rocks when you're doing custom controls.
Edit: On the I18N/G11N front, here's more info: the shaping engines for international text have been updated quite a bit in the Uniscribe subsystem [2] of the Windows operating system, but not in GDI+ subsystem. So sometimes things looked strange/wrong if your .NET app was using the Graphics based method (AKA, GDI+). However, using the TextRenderer approach (AKA, Uniscribe) eliminates these problems and allows you to render text correctly (perfectly?) in the new locales introduced with Windows XP SP2 [3] (such as Bengali and Croatian). (Caveat emptor: I have no idea how or even if either of these methods play with vendor specific extensions to specific code pages.)
[1] http://blogs.msdn.com/jfoscoding/archive/2005/10/13/480632.aspxIEnumerable<T>
isn't used nearly enough if you ask me.
System.Convert [1] is a lot nicer than people think.
It's a bit more forgiving on what you put in. Use Reflector [2] to see how it converts between different types.
Ints are defaulted to 0 from bad input, bools to false and so on.
It's made int.Parse, bool.Parse and all other .Parse almost obsolete for me. TryParse is still usefull for the most secure parsing.
[1] http://msdn.microsoft.com/en-us/library/system.convert.aspxI didn't know about System.Net.WebClient [1] until it was posted in an answer to a question of mine [2].
WebClient client = new WebClient ();
client.DownloadFile("http://stackoverflow.com/", "target.html");
client.UploadFile("http://mysite.com/", "hello.txt");
[1] http://msdn.microsoft.com/en-us/library/system.net.webclient%28VS.80%29.aspxSystem.Web.VirtualPathUtility
Provides utility methods for common virtual path operations.
http://msdn.microsoft.com/en-us/library/system.web.virtualpathutility.aspx
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim sb As New StringBuilder()
Dim pathstring As String = Context.Request.FilePath.ToString()
sb.Append("Current file path = " & pathstring & "<br />")
sb.Append("File name = " & VirtualPathUtility.GetFileName(pathstring).ToString() & "<br />")
sb.Append("File extension = " & VirtualPathUtility.GetExtension(pathstring).ToString() & "<br />")
sb.Append("Directory = " & VirtualPathUtility.GetDirectory(pathstring).ToString() & "<br />")
Response.Write(sb.ToString())
Dim sb2 As New StringBuilder()
Dim pathstring1 As String = Context.Request.CurrentExecutionFilePath.ToString()
sb2.Append("Current Executing File Path = " & pathstring1.ToString() & "<br />")
sb2.Append("Is Absolute = " & VirtualPathUtility.IsAbsolute(pathstring1).ToString() & "<br />")
sb2.Append("Is AppRelative = " & VirtualPathUtility.IsAppRelative(pathstring1).ToString() & "<br />")
sb2.Append("Make AppRelative = " & VirtualPathUtility.ToAppRelative(pathstring1).ToString() & "<br />")
Response.Write(sb2.ToString())
End Sub
Not really hidden but:
System.Web.Security.FormsAuthentication
.HashPasswordForStoringInConfigFile(string password, string format)
Does the simple and common task of getting the MD5 or SHA1 hash of a given string. Since almost every system I have ever written stored password hashes instead of encrypted data or the plaintext, this is a godsend to avoid mucking about with the Crypto stuff.
It saved me a lot of time. And it helped Stack Overflow users to solve their problems:
Buffer.BlockCopy [1]
Also StringReader [2] and StringWriter [3].
Oops forgot about: Debugger.Break [4]
[1] http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspxYou can play default windows sounds this way :
System.Media.SystemSounds.Beep.Play();
...
System.Media.SystemSounds.Question.Play();
Tired of typing the unwieldy
string.Equals(x, y, StringComparison.CurrentCultureIgnoreCase)
?
Instead, try one of the properties on the StringComparer class:
Instead of the above, you can type:
StringComparer.CurrentCultureIgnoreCase.Equals(x, y);
Even though it's only slightly shorter, it's nice because it keeps the focus on the two things you're comparing, without the distraction of the StringComparison.CurrentCultureIgnoreCase
parameter. And you can break it up if you like:
var comparer = StringComparer.CurrentCultureIgnoreCase;
comparer.Equals(x, y);
[1] http://msdn.microsoft.com/en-us/library/system.stringcomparer%5Fproperties.aspxOrdinalIgnoreCase
- SLaks
static bool EqualsIgnoreCase(this string me, string that) { return string.Equals(me, that, StringComparison.CurrentCultureIgnoreCase); }
- Mr. S
HashSet<T>
. It is a new class in the .NET Framework 3.5 and is very similar to List<T>
only better.
http://blogs.msdn.com/bclteam/archive/2006/11/09/introducing-hashset-t-kim-hamilton.aspx
For some reason many people don't kow about System.Text.StringBuilder. I couldn't live without it!
The BitConverter.ToString [1] method is very useful when working with binary data. I use it for debugging, traces and within unit testing.
It will take a byte array and return a printable string representation - something like "04-08-01-23-45-67-89-AB-CD-EF".
I also use Regex.Split(string, string) [2] for splitting a delimited strings.
It is somewhat similar to String.Split() [3], but using Regex.Split() is much more intuitive: Regex.Split() result string array only contain the data you need, while String.Split() result also contains the delimiters.
[1] http://msdn.microsoft.com/en-us/library/system.bitconverter.tostring.aspxString.Empty
seems to be a hidden feature for many developers. String.IsNullOrEmpty(string)
too.
string.Empty
is obsolete, and you should use ""
now (it’s more readable, too). - Timwi
string.Empty
a “hidden feature”? It’s completely useless, you can just write ""
instead. Why don’t we also have a char.Space
for ' '
and an int.Zero
for 0
? :-p - Timwi
string.IsNullOrEmpty
is for those who still don't know about string.IsNullOrWhitespace
unless empty string check needed. - Shimmy
System.IO.Path.Combine
Use this instead of concatenating the 2 strings yourself.
This is cool. VisualStyleInformation Class [1] provides a lot of information about the current visual style of the operating system.
System.Diagnostics.Debugger.Break() [2] is used by virtually everyone but is very convenient for debugging .NET services.
NetworkChange.NetworkAvailabilityChanged Event [3] makes it easy to monitor network availability.
[1] http://msdn.microsoft.com/en-us/library/system.windows.forms.visualstyles.visualstyleinformation.aspxHere's a little snippet to tell which class/method the call is coming from. Useful in some special situations:
StackFrame frame = new StackFrame(1);
frame.GetMethod().Name; //Gets the current method name
MethodBase method = frame.GetMethod();
method.DeclaringType.Name //Gets the current class name
If you have a very complicated object to debug and don't want to spend the time creating a Visualizer to get a specialized view, you can use the built-in HTML Visualizer by creating a ToHtmlString()
method in your class. This is based on the fact that the .NET debugger very reliably allows you to add function calls in your watch windows.
Here's an example I recently did of presenting an interleaved time-lapse view of the data state throughout a group of tasks:
ToHtmlString
return?? - Shimmy
System.Web.UI.WebControls.MailDefinition [1]
"The MailDefinition class can be used by controls to create a MailMessage object from a text file or a string that contains the body of the e-mail message. Use the MailDefinition class to simplify creating predefined e-mail messages to be sent by a control."
[1] http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.maildefinition.aspxWeakReference [1]. Extract from here [2] ...
The garbage collector cannot collect an object in use by an application while the application's code can reach that object. The application is said to have a strong reference to the object.
A weak reference permits the garbage collector to collect the object while still allowing the application to access the object.
This can be used to implement weak events, see here [3]
Deep comparison of XmlTrees
[1] http://msdn.microsoft.com/en-us/library/system.weakreference.aspxCompares the values of two nodes, including the values of all descendant nodes.
I don't think it's a hidden feature, but I don't see it used often:
[System.Diagnostics.DebuggerStepThrough]
Quite useful when you have a pile of accessor-type functions or something which you don't want to be stepping into while debugging.
I just found:
System.Security.Cryptography.ProtectData
Used to encrypt data for the current user or the local machine.
I have to add Exception.GetBaseException() [1]. I can't know how many times I've this code instead:
while(e.InnerException != null)
e = e.InnerException;
return e.Message;
instead of just:
return e.GetBaseException().Message;
[1] http://msdn.microsoft.com/en-us/library/system.exception.getbaseexception.aspxConvert hexadecimal\octal\binary string to decimal:
Convert.ToInt32("2A", 16); // equals 42
Convert.ToInt32("52", 8); // equals 42
Convert.ToInt32("101010", 2); // equals 42
A great way to convert numbers to byte array:
byte[] bytes = BitConverter.GetBytes(32767);
Or better, use Jon Skeet's MiscUtil [1] for endian bit conversion.
[1] http://www.yoda.arachsys.com/csharp/miscutil/Convert.ToString(42, 16)
. Interestingly, it works only for bases 2, 8, 10 and 16... other bases throw an exception. This is kind of strange, since the same implementation could support all bases up to 36 (at least). - Thomas Levesque
I'd have to say System.ComponentModel.BackgroundWorker
.
It's not exactly easy to use, because you still have to understand how asynchronous method calls work, and you have to know about avoiding cross-thread exceptions, using Invoke
to update the UI, etc. But it's considerably easier to use than System.Threading.Thread
, which is what a lot of developers gravitate towards when they need to implement a background process.
String.Format(). Allows you to get rid of the wonkiness of "This" + " is" + " my favorite " + " Application";
Very helpful class to measure performance
System.Diagnostics.StopWatch
[1]
See detailed posts
here
[2]
More of a runtime feature, but I recently learned that there are two garbage collectors. The workstation gc and the server gc. Workstation is the default, but server is much faster on multicore machines.
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
Be careful. The server gc requires more memory. See documentation [1] for more information.
[1] http://msdn.microsoft.com/en-us/library/ms229357.aspxI use these built-in delegate types (and their "overloaded" cousins) all the time:
Func<T, TResult>
[1]
Action<T>
[2]
Predicate<T>
[3]Along with Lambdas is C# 3.0 they're pretty useful and can help make things more readable. (You can of course still use them with C# 2.0 and anonymous delegates).
[1] http://msdn.microsoft.com/en-us/library/bb549151.aspx
System.Diagnostics
[1] namespace contains many "hidden" gems. I have used extensively the
DebuggerStepThroughAttribute
[2], I have subclassed many times the
TraceListener
[3] class and I want to see in more detail the
PerformanceCounter
[4].
Create custom size thumbnails from any image using System.Drawing.Image.GetThumbnailImage [1]:
public Image GetThumbnailImage (int thumbWidth, int thumbHeight,
GetThumbnailImageAbort callback, IntPtr callbackData)
Eg usage:
public static Image GetThumbnailFromImage(System.IO.Stream file)
{
return Image.FromStream(file).GetThumbnailImage(48, 48, null, new IntPtr());
}
[1] http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspxHere's one, inspired by Marcc [1]'s related Diagnostics attribute [2]:
System.Diagnostics.DebuggerDisplay [3]
It allows you to define the format of the string displayed in the Immediate / Locals window of Visual Studio, providing a string like "Person: {name} Cars: {cars.Count}" will display in the windows like "Person: John Doe Cars: 2".
[1] http://stackoverflow.com/users/101280/marccSystem.Runtime.Remoting.Proxies.RealProxy [1].
This class is pretty esoteric and normally only used in weird remoting scenarios; however, I have used it for the ability to dynamically implement an interface. It is also used by some mocking frameworks for the same purpose. See also Extending RealProxy [2].
[1] http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspxType.TryParse()
Environment.NewLine
System.Net.Mail.MailAddress - no more regexp for server-side email address validation ;)
MatchEvaluator Delegate [1]: Represents the method that is called each time a regular expression match is found during a Replace method operation.
[1] http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchevaluator.aspxSystem.Linq is saving me a lot of time on Visual Studio 2008.
System.Text.UTF8Encoding [1] for converting streams.
[1] http://msdn.microsoft.com/en-us/library/system.text.utf8encoding.aspxIf you are drawing custom Windows Forms controls, then the following classes are essential for your OnPaint() method (or Paint event):
using System.Windows.Forms;
These classes all provide methods that will do most of the drawing work for you and keep your controls looking professional and native.
[1] http://msdn.microsoft.com/en-us/library/system.windows.forms.controlpaint.aspxIf you're trying to convert between big/little endian then there is IPAddress.HostToNetworkOrder [1] and IPAddress.NetworkToHostOrder [2]. Why these methods were not part of the BitConverter class and in the obvious place people will look we'll never know.
[1] http://msdn.microsoft.com/en-us/library/system.net.ipaddress.hosttonetworkorder.aspxTypeDescriptor [1] when using Windows Forms [2] data binding. This is how BindingSource can pretend to be any other object type.
[1] http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspxstring.Join([separator], [array])
Couple this with LINQ and it rocks!
string.Join(",", customers.Select(c => c.Name).ToArray());
All your customer names in a CSV with one line of code :-)
Using StackFrame to get information about calling method and running class. You can travel the stack and get the methodName, calling calss etc. You can get the stackFrame using
StackFrame frame = new StackFrame(n);
Where n is the layer above the current call And then you can retrive information by using its properties. for example use the following the get the information of the calling method:
MethodBase methodBase = frame.GetMethod();
BaseValidator [1] Makes writing Custom validated controls much easier.
[1] http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator(VS.80).aspxSystem.Runtime.InteropServices.Marshal
I hate having to do interop, and particularly PInvoke, but there are all kinds of goodies in Marshal for turning function pointers into delegates, and vice versa, turning Win32 error codes into something a little more helpful (often only a little though), and so on.
I came across this today System.Data.SqlTypes.SqlDateTime [1]
it has
System.Data.SqlTypes.SqlDateTime.MinValue;
System.Data.SqlTypes.SqlDateTime.MaxValue;
among other methods & properties.
[1] http://msdn.microsoft.com/en-us/library/system.data.sqltypes.sqldatetime.aspxFormatterServices.GetUninitializedObject [1]
Creates a new instance of a type without calling any constructor. This will work with private constructors, non-parameterless-constructors, any type of constructor (since they aint called).
I believe this is the only way to ensure that a static constructor on a type is executed if you only have a Type instance. (You can not invoke it with reflection, and the Activator may fail due to nonmatching constructors.)
A somewhat esoteric problem, and solution.
[1] http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject.aspxMy favorite hidden feature is the SDK. OK, not very hidden, for some people, but most people seem to be able to develop .NET applications only with a tool or IDE, like Visual Studio. The SDK is free, and for small applications it's way quicker for me to write them up in emacs and then just build them with the command line compilers, csc.exe or vbc.exe.
Plus all the SDK tools are handy, too. XML Schema Definition Tool [1] (xsd.exe), Strong Name Tool [2] (sn.exe), and many others.
[1] http://msdn.microsoft.com/en-us/library/x6c1kb0s%28VS.71,printer%29.aspxIn line with String.IsNullOrEmpty().....
String.Empty
usage:
string s = String.Empty;
//OR
string s = string.Empty;
instead of
string s = "";
System.Configuration.Install.AssemblyInstaller [1] to install services programmatically [2]
[1] http://msdn.microsoft.com/en-us/library/system.configuration.install.installer.aspxMembership.GeneratePassword()
(
msdn
[1]) will generate a secure temporary password for you.
System.Xml.XmlConvert [1] contains lots of nice static methods to convert between XSD types and .Net types.
[1] http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.aspxI found several cases where people were not aware of certain properties of the Environment
class. In particular, I cleaned up several places in code and changed it to:
Environment.NewLine
[1] (unit testing a templating engine that runs in Mono on *nix and .NET on Windows = HUGE improvement)
Environment.CurrentDirectory
[2] (replaced Path.GetFullPath('.')
throughout a file-manipulating utility)The Managed, Native, and COM Interop Team [1] at CodePlex have released a modified, open source TlbImp tool [2] that allows simple creation of customized wrappers for pesky COM libraries.
[1] http://clrinterop.codeplex.com/System.Environment [1] is one of my favorites. Especially the WorkingSet [2] property (gets the amount of physical memory mapped to the process context).
[1] http://msdn.microsoft.com/en-us/library/system.environment.aspxSystem.Reflection.Assembly.GetExecutingAssembly.Location
Gets the path (and name) of the current running application.
I have a few related commands at my Blog [1]
[1] http://blogs.microsoft.co.il/blogs/dhelper/archive/2008/08/18/how-to-find-assembly-path-name-and-version-at-runtime.aspxSystem.Security.SecurityElement.Escape [1]
Escapes XML entities from a string so you can use it within an XML element. It's used by the framework in generation WS-Security XML, but saves four string replace statements in your own code.
[1] http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape.aspxEasy way of making an MD5 or SHA1 hash [1]:
string hash = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("string to hash", "MD5");
Quick way of generating a unique, temporary file on disk:
string tempFilePath = System.IO.Path.GetTempFileName();
The System.Web.VirtualPathUtility [2] class also has some interesting methods for manipulating file paths.
Parse an enum into a string array in one line (eg. get all known colours from KnowColor enumeration into an array):
string[] colours = System.Enum.GetNames(typeof(System.Drawing.KnownColor));
If you want to annoy your server admin when he's at the console, add this to your web app :D
System.Media.SystemSounds.Exclamation.Play();
[1] http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.hashpasswordforstoringinconfigfile%28VS.80%29.aspxI like to use System.Collections.CaseInsensitiveComparer [1] to compare strings.
[1] http://msdn.microsoft.com/en-us/library/system.collections.caseinsensitivecomparer.aspxMicrosoft.VisualBasic.IsNumeric(object)
Despite being in the Microsoft.VisualBasic.dll assembly, this method can be called by C# just as easily and can quickly let you know if the object being tested can be evaluated as a number.
Related to it are the various TryParse()
methods, which attempt to evaluate an object as a number but don't raise exceptions if the call fails... These can be found under a variety of different types such as System.Int32
and System.DateTime
The Action lambda is a delegate and hence gets the same delegate goodies that regular ones do - such as BeginInvoke():
new Action(() => MethodIWantToRunAsychronously())
.BeginInvoke(new AsyncCallback(x => ThingToDoWhenMethodReturns()), null);
What it does: Spawns a new thread and runs MethodIWantToRunAsychronously() on it while your continuing to execute the current method on the current thread. When MethodIWantToRunAsychronously completes, ThingToDoWhenMethodReturns() is called (still) on the new thread.
EndInvoke
. If you just want fire-and-forget, call ThreadPool.QueueUserWorkItem(() => SomeMethod());
- SLaks
ToString() method of Object base class is really nice thing. Override it then bring mouse over instance variable in debug time after instance variable created. Don't even need DebuggerDisplay
class Program
{
string name;
string surname;
static void Main(string[] args)
{
Program instance = new Program() { name = "James", surname = "hetfield" };
Console.ReadKey();
}
public override string ToString()
{
return string.Format("name is {0}, surname is {1}",name,surname);
}
}
System.Runtime.InteropServices.RuntimeEnvironment [1]
Most notably the GetRuntimeDirectory() method; however, there are several useful methods there.
// Show whether the EXE assembly was loaded from the GAC or from a private subdirectory.
Console.WriteLine("Did the {0} assembly load from the GAC? {1}",
Assembly.GetExecutingAssembly(),
RuntimeEnvironment.FromGlobalAccessCache(Assembly.GetExecutingAssembly()));
// Show the path where the CLR was loaded from.
Console.WriteLine("Runtime directory: {0}",
RuntimeEnvironment.GetRuntimeDirectory());
// Show the CLR's version number.
Console.WriteLine("System version: {0}",
RuntimeEnvironment.GetSystemVersion());
// Show the path of the machine's configuration file.
Console.WriteLine("System configuration file: {0}",
RuntimeEnvironment.SystemConfigurationFile);
[1] http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.runtimeenvironment.aspx[System.Diagnostics.ConditionalAttribute] - can be used instead of ugly preprocessor directives. For instance:
[Conditional("DEBUG")]
public void Validate()
{
// ...
}
This isn't really a method but just something I found in the String [1] class source:
// The Empty constant holds the empty string value.
// We need to call the String constructor so that the compiler doesn't mark this as a literal.
// Marking this as a literal would mean that it doesn't show up as a field which we can access
// from native.
public static readonly String Empty = "";
[1] http://www.koders.com/csharp/fid6135F77482E6125D97DC3197AD53876AE1098662.aspxDecimal
preserves trailing zeros :
decimal x = 1.0m;
decimal y = 1.00m;
decimal z = 1m;
Assert.IsTrue(x == y);
Assert.IsFalse(x.ToString() == y.ToString());
Assert.AreEqual("1.0", x.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1.00", y.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1", z.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1.000", (x*y).ToString(CultureInfo.InvariantCulture));
This behavior is documented in the MSDN library.
The decimal.Parse
method keeps track of trailing zeros too :
decimal x= decimal.Parse("1.0", CultureInfo.InvariantCulture);
decimal y= decimal.Parse("1.00", CultureInfo.InvariantCulture);
Assert.AreEqual("1.0", x.ToString(CultureInfo.InvariantCulture));
Assert.AreEqual("1.00", y.ToString(CultureInfo.InvariantCulture));
The DebuggerStepThroughAttribute is great for properties and also for those helper functions that you have no desire to step through. Unfortunately, it seems rarely known:
http://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerstepthroughattribute.aspx
Expanding the My Namespace has always been useful to me
Namespace My
<Global.Microsoft.VisualBasic.HideModuleName()> _
Friend Module MyStuff
Sub Foo()
End Sub
End Module
End Namespace
Ignore Attribute [1] on Unit-Tests for ignoring slow performance tests during development
[1] http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.ignoreattribute.aspxpublic static int Compare(string strA, string strB, bool ignoreCase)
Great to compare two strings with possible difference in letter case.
For generating code files I like System.CodeDom.
If you have a custom MSBuild task in your project that processes a file and subsequently creates .cs
files to include in the same build, changes to the source file of the transformation often won't show in debugging without building twice. When you are generating a single file based solely on the content of a single source file, this task is best solved with a SingleFileGenerator. For multiple inputs and/or outputs, you may be stuck with an MSBuild task. In this case you can fix Visual Studio's dependency analysis by adding the following to your .csproj
file:
<PropertyGroup>
<UseHostCompilerIfAvailable>False</UseHostCompilerIfAvailable>
</PropertyGroup>
It's introduces a few other annoyances, but it will allow you to have deterministic, correct single builds (a rather important goal).
I recently discovered the
ProtectedData
[1] and
ProtectedMemory
[2] classes, which allow you to use the Data Protection API from .NET. It's a nice way to encrypt user credentials for storage in applications that need to authenticate on a remote server.
public static string EncryptPassword(string password, byte[] optionalEntropy = null)
{
byte[] clearTextBytes = Encoding.UTF8.GetBytes(password);
byte[] encryptedBytes = ProtectedData.Protect(clearTextBytes, optionalEntropy, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(encryptedBytes);
}
public static string DecryptPassword(string encryptedPassword, byte[] optionalEntropy = null)
{
byte[] encryptedBytes= Convert.FromBase64String(encryptedPassword);
byte[] clearTextBytes = ProtectedData.Unprotect(encryptedBytes, optionalEntropy, DataProtectionScope.CurrentUser);
return Encoding.UTF8.GetString(clearTextBytes);
}
[1] http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspxFormatterServices.GetUninitializedObject Activator.CreateInstance
Has someone mentioned above two?
while(true)
Navigate()
;
- Shimmy