Reading "More Effective C#" I came across a pretty cool bit (around p.55) about using the tuple type to return more than one value from a method. That's fair enough but the really cool part was the way the author used the using keyword...
For example, in returning a latitude, longitude from a method (you could be returning five or six values etc. with a tuple but lets use two for simplicity) Tuple<int, int> doesn't really tell us too much.
public static Tuple<string, decimal> GetLocation(string address)
{
int longitude = // get longitude algorithm
int latitude = // get latitude algorithm
return new Tuple<int, int>(longitude, latitude);
}
//usage
Tuple<int, int> weather = GetLocation("address");
To give a more meaningful return name you can provide an alias for the return value.
using GeoLocation = Tuple<int, int>;
public static GeoLocation GetLocation(string address)
{
int longitude = // get longitude algorithm
int latitude = // get latitude algorithm
return new GeoLocation(longitude, latitude);
}
// usage
GeoLocation location = GetLocation("address");
The using keyword continues to surprise me (e.g. as a tidy way of attempting to dispose of something without knowing whether or not it implements IDisposable). Of course if this method was simply better named "GeoLocation" there's be no problem! But it's the concept that's useful to know.
In a multithreaded WinForm app, one of the most common exceptions you'll see is in trying to access a form, or controls on a form, from a different thread than the one it was created on. Fortunately there is an easy way to check if a control is being accessed from the thread it was created on - the InvokeRequired property.
This simply checks if the handle was created on the same thread as the caller. If this Property is set to true then you need to marshal the call to the UI across the thread. There are methods provided for this too - use Invoke and BeginInvoke to correctly marshal the call to the thread that created the Control. From MSDN, Control.Invoke"Executes the specified delegate on the thread that owns the control's underlying window handle".
Most of the code snippets you see on the web for this are out-of-date. Although they work well there are better solutions using built-in features of .NET that results in less code (woo-hoo!).
The old way is to declare a custom delegate
public delegate void UpdateFormTextChanged(string message);
Then you will see that delegate being invoked from the form. If parameters are to be passed they are done in an object array (yuck).
public void UpdateProgressMessage(string message) { if (!InvokeRequired) { DownloadStatusTextBox.Text = message; } else { UpdateFormTextChanged updateText = SetProductName; Invoke(updateText, new object[] { productName }); } }
A simpler way of doing this without the need to create custom delegates is to use Action<T> which takes one parameter and returns void. You replace T with your parameter type making it strongly typed - no objects or object arrays.
public void UpdateProgressMessage(string message) { if (!InvokeRequired) { DownloadStatusTextBox.Text = message; } else { Invoke(new Action<string>(UpdateProgressMessage), message); } }
For a method with no parameter and void return type you can use the Action() method (in .NET 3.5 and higher) or MethodInvoker in .NET 2.0
For more than one parameter you can use one of the many overloads of Action<T>. But wait! I don't see any available in .NET 2.0. Yeah, .NET 2.0 includes Action<T> but not Action<T1, T2> or Func<T, TResult> etc. but it does support Generics of course so you can write your own delegates to mimic these 3.5 features. For example, if you want to call a method on a form that has two parameters - for example, updating a progress bar
public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
public void UpdateProgress(int total, int downloaded) { if (!InvokeRequired) { ProgressBar.Maximum = total; ProgressBar.Value = downloaded; } else { Invoke(new Action<int, int>(UpdateProgress), new object[] {total, downloaded}); } }
I do not agree with the mantra that you should NEVER swallow exceptions. I know some people who will fight you on the spot for suggesting otherwise but like any rule there are always exceptions. Don't get me wrong, I think it is a great rule-of-thumb and should be followed most of the time but I've come across a case recently where I swallow exceptions and I don't feel guilty about it...
Logging throws an exception
Sometimes you don't care if logging fails. Sometimes logging is really not that important and you absolutely do not want to interrupt the application (and the Customer) just because logging has failed. Right?
try { Logger.Write(message); } catch { }
So there is a real-life scenarios where I think it is okay to swallow an exception...Here is a good discussion on the topic on StackOverflow
If you have multiple anonymous types that have the same Properties, with the same type and in the same order then the compiler treats them as the same type.
For example, if I have two anonymous types declared as follows
var a = new { Name = "Peter" }; var b = new { Name = "Peter" };
The compiler sees these as the same type (the Properties are both called Name, they are both of type string and all the Properties are in the same order). Because Anonymous Types inherit from System.Object you can check if these two instances are equal using Equals(). Anonymous Type instances will be equal if their properties are equal. So the following outputs "True" because the Name properties are equal (strings that match exactly).
Console.WriteLine(a.Equals(b));
However, if I changed the case of one the Names to "peter", this would result in "False" because the two properties are no longer equal - String overrides Equals and ignores case in the checking for equality. It is also worth noting that using operators when checking for equality will not give you the result you might be expecting. You cannot have any members in an Anonymous Type other than Read-Only Properties meaning you cannot override a method from System.Object including operators. So the following code results in "False".
var a = new { IsAnon = true }; var b = new { IsAnon = true }; Console.WriteLine(a == b);
Recently I needed to change the Start Type of a Windows Service from another application. Some PCs were infected with the Conficker worm. One of the things this worm does is shut down some Windows features that might help in discovering/removing the worm. One of the services it affects is BITS - used in downloading Windows Updates - by stopping the service and changing it's start mode to Disabled.
There is a managed option in .NET - the System.ServiceProcess.ServiceController class which exposes some useful Properties and Methods for managing a Service. However, it provides no way to change the start mode of a Service. In looking into this I came across this question on StackOverflow which suggests the best way to achieve this is through the Win32 API using P/Invoke.
The awesome wiki pinvoke.net is a great resource to get started. It has helped me many times in the past and it certainly helped me to write some of this code here.
First of all we need to make calls to functions in the advapi.dll. We need to call ChangeServiceConfig, OpenSCManager and OpenService.
ChangeServiceConfig is where we can actually make the change we want to the Start Mode. But you need to pass this a handle to a service. So we also need to call OpenService. This in turn requires a handle to a SCManager so we need to call
OpenSCManager. Here is the code - feel free to use and improve. It is a static class that provides one method ChangeStartMode
public static class ServiceHelper
{
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Boolean ChangeServiceConfig(
IntPtr hService,
UInt32 nServiceType,
UInt32 nStartType,
UInt32 nErrorControl,
String lpBinaryPathName,
String lpLoadOrderGroup,
IntPtr lpdwTagId,
[In] char[] lpDependencies,
String lpServiceStartName,
String lpPassword,
String lpDisplayName);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(
IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr OpenSCManager(
string machineName, string databaseName, uint dwAccess);
[DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
public static extern int CloseServiceHandle(IntPtr hSCObject);
private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
private const uint SERVICE_QUERY_CONFIG = 0x00000001;
private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
public static void ChangeStartMode(ServiceController svc, ServiceStartMode mode)
{
var scManagerHandle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
if (scManagerHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Manager Error");
}
var serviceHandle = OpenService(
scManagerHandle,
svc.ServiceName,
SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
if (serviceHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Error");
}
var result = ChangeServiceConfig(
serviceHandle,
SERVICE_NO_CHANGE,
(uint)mode,
SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
null,
null,
null);
if (result == false)
{
int nError = Marshal.GetLastWin32Error();
var win32Exception = new Win32Exception(nError);
throw new ExternalException("Could not change service start type: "
+ win32Exception.Message);
}
CloseServiceHandle(serviceHandle);
CloseServiceHandle(scManagerHandle);
}
To use this just provide an instance of ServiceController and a ServiceStartMode.
var svc = new ServiceController("BITS");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
// You can then Start the service if necessary.
if (svc.Status != ServiceControllerStatus.Running)
{
svc.Start();
}
// And of course you should close the service when no longer needed
svc.Close();
When it comes to member variables I prefer an underscore and I'm not going to apologize to the Hungarian notation police! It fits my eye and I like the way it looks in my code. However, the team that I currently work in has different ideas and the standard is to use "this" everywhere...
Now I'm okay with this obviously. Whatever the team chooses is fine by me and once everybody agrees to use the same standards then that is the important thing.
It is interesting that Resharper highlights the redundancy of it by default Qualifier 'this.' is redundant and Stylecop warns you to include it! I find it litters up your code pretty quickly with noise.
Anyhow, I really wanted to find out the uses of the keyword that are not related to style. So here is a list of required uses (i.e. you absolutely have to use it and it is not just a style choice)
To qualify members hidden by the same name
To have an object pass itself as a parameter to other methods
To have an object return itself from a method
To declare indexers
To declare extension methods
To pass parameters between constructors
To internally reassign value type (struct) value.
In these cases the 'this' keyword has a clear purpose, in all other cases it is a style issue. Of course the key thing here is that it really doesn't matter. The compiled code has the IL equivalent of this inserted anyway whether or not you include it in your code and there are definitely more important things to worry about!
There is no way currently of constraining a Generic type to ensure it is serializable at compile-time. However, there is a quick and easy way to check.
if (!typeof(T).IsSerializable) { throw new ArgumentException("type is not serializable"); }
When you create a Generic class and constrain the Type parameter T, you are actually increasing the number of operations available. I know it sounds like a contradiction but it makes sense when you think about it. By constraining my Type parameter with an Interface for example, I get access to all the operations that Interface defines. If you do not apply a constraint then you are limiting yourself to operations on System.Object!
Quick example...
public interface IPerson { int Age { get; set; } }
public class PersonRepository<T> where T : IPerson { private T m_person;
public PersonRepository(T person) { this.m_person = person; }
public void Save() { // The Age property is available if (this.m_person.Age > 65) { // Save to free bus pass database... } } }