While there are more complex and functional lock mechanisms, I wanted a very simple lock that would tell me if an operation was locked or not. Normally I would just have a flag that’d be true or false, but I found that it was not always easy to remember to set the flag on or off, and also to make sure the flag was set at the right place. So I came up with this class :
public class BooleanLock
{
public bool Locked { get; private set; }
public class BlockLock : IDisposable
{
private BooleanLock _parent;
public BlockLock(BooleanLock parent)
{
_parent = parent;
_parent.Locked = true;
}
#region IDisposable Members
public void Dispose()
{
_parent.Locked = false;
}
#endregion
}
public BlockLock Lock()
{
return new BlockLock(this);
}
}
Now I could use it this way :
private BooleanLock _myUpdateLock = new BooleanLock();
private void UpdateSomeProperty(bool reset)
{
if (_myUpdateLock.Locked)
return;
And here’s where the lock is set :
private void OnSomePropertyChanged()
{
if (some-condition)
{
using (_myUpdateLock.Lock())
{
} <-- lock is released here automatically
The big advantage here is that the C# compiler’s using-block behavior handles complex try-catch scenarios that I would otherwise have had to implement on my own.
Tags: C#/.NET
The DesignMode property does not always return the correct value, specially for nested controls or for child controls instantiated in their parent control’s constructors. One workaround is to check for LicenseManager.UsageMode and see if it’s equal to LicenseUsageMode.Runtime, but even that won’t work all the time. It will always return Runtime from event handlers and worker threads, so a more guaranteed approach is to see if the current process-name is devenv. Of course that’s a slightly heavier call so we should still check for LicenseManager.UsageMode first, and only check the process-name if we have to.
bool isDesignMode = LicenseManager.UsageMode == LicenseUsageMode.Designtime
|| Process.GetCurrentProcess().ProcessName.ToLowerInvariant().Contains("devenv");
Tags: C#/.NET · Windows Forms
Unless you specifically want to expose a List<T> via a public interface (either as a return type or as a method argument), it’s a better idea to expose an IList<T>, ICollection<T>, or even an IEnumerable<T> depending on your needs. Recently I had to implement a generic list class that implemented property notifications and for this purpose I wrote a collection class that implemented IList<T> which by the way implements both ICollection<T> and IEnumerable<T>. I thought it’d be a simple matter to change members of certain types that used a List<T> to use this new collection class.
Unfortunately, I found that there were several methods in containing classes as well as calling classes that expected List<T> objects (even though the callers only used IList<T> or ICollection<T> members). Eventually I ended up having to change calling code and utility helper methods to use an IList<T> or ICollection<T> as appropriate. (Note that exposing the notification list was out of the question as it was not accessible to some of the callers and it is not good practice anyway).
In some cases the code used List<T> specific methods like Find, but if you have LINQ available then you don’t need to use the List<T> methods since you have alternate and usually more useful extension methods that you can use. I suppose I am over-specializing here by talking about List<T> in particular because it’s probably a good general practice to always expose the least derived class that you really need to.
Note that if you really need to expose a solid class without letting the users change the collection, then using ReadOnlyCollection<T> would be the correct approach compared to directly exposing the List<T> or Collection<T> object or their related interfaces like IList<T>.
Tags: C#/.NET
Continuing on from my previous blog entry, in this entry I will talk about variant generic delegates. Just as with generic interfaces, generic delegates can use out and in to specify covariant and contravariant parameters respectively. And the MSIL equivalents are the + and - symbols.
Here are three variant generic delegate declarations:
delegate T CovariantDelegate<out T>();
delegate void ContraVariantDelegate<in T>(T t);
delegate T1 ContraAndCovariantDelegate<out T1, in T2>(T2 t2);
The rules are the same as with generic interfaces. The covariant delegate can only use the generic parameter as a return type, while the contravariant delegate can only use it as a delegate argument and not as a return type. The third delegate is both covariant and contravariant but with respect to two separate parameters. And here’s how these delegates can be used:
static Derived SomeFunc()
{
return new Derived();
}
static void SomeOtherFunc(Base b)
{
}
static Derived AnotherFunc(Base b)
{
return new Derived();
}
private void DoDelegates()
{
CovariantDelegate<Base> covariantDeleg = SomeFunc; <--(#1)
ContraVariantDelegate<Derived> contraDeleg = SomeOtherFunc; <--(#2)
ContraAndCovariantDelegate<Base, Derived> contraCovarDeleg = AnotherFunc; <--(#3)
}
(#1) : Covariance at play here. Even though SomeFunc returns a Derived type, we use it to instantiate a delegate that expects a Base type.
(#2) : Contravariance here. The delegate expects a Derived argument, but we pass it a method that takes a Base argument.
(#3) : This is essentially a mix of (#1) and (#2).
Here’s a more realistic use of variance in generic delegates:
class Item
{
. . .
public int Code { get; set; }
}
class Book : Item
{
public string Title { get; set; }
}
class DVD : Item
{
public string Description { get; set; }
public int Duration { get; set; }
}
Item FindItem(string searchText, Func<string, Item> findFunc)
{
return findFunc(searchText);
}
Notice how the FindItem method’s second parameter is a Func<> object that itself takes a string and returns an Item. Func’s return type parameter is covariant, and that’s what we can take advantage of. The code below shows two methods, one that searches for a book, and the other that searches for a DVD.
static List<Book> books = < . . . >
static Book FindBook(string searchText)
{
return books.FirstOrDefault(book => book.Title == searchText);
}
static List<DVD> dvds = < . . . >
static DVD FindDVD(string searchText)
{
return dvds.FirstOrDefault(dvd =>
dvd.Description.StartsWith(searchText)
|| searchText.Contains(dvd.Duration.ToString()));
}
The following code shows how to call FindItem using a delegate of our choice.
Item book = FindItem("C++/CLI in Action", FindBook);
Item dvd = FindItem("Batman", FindDVD);
In the first call, we pass a method that returns a Book, whereas the method signature expects a method that returns an Item. But since Func<>’s return parameter is covariant, this works fine. Essentially we are passing a Func<string, Book> as a Func<string, Item> argument. It’s the same for the second call too except that we have a DVD instead of a Book.
Now let’s see a contravariant delegate example. Consider the following method:
void ShowItemCode<T>(T item, Action<T> showFunc)
{
showFunc(item);
}
It takes an Action<T> as the second argument which is a contravariant generic delegate. Now consider the following code:
static void ShowCode(Item item)
{
Console.WriteLine(item.Code);
}
. . .
Book book = < initialize here . . .>
ShowItemCode(book, ShowCode);
DVD dvd = < initialize here . . .>
ShowItemCode(dvd, ShowCode);
In the first case we are calling ShowItemCode<Book> which expects Action<Book> as the second argument. But we pass ShowCode(Item) which matches Action<Item> yet it works because Action<> is contravariant.
Remember how in the previous entry I had mentioned a case where a covariant parameter type can be used as the parameter type for a contravariant delegate argument? Well, here’s an example of that:
interface ITestCovariant<out T>
{
void Foo1(Action<T> func);
void Foo2(Func<T, bool> func);
}
Even though T is a covariant parameter, we can use it as the parameter type for Action<> since Action is contravariant. I have also used it as the first type argument for the Func<> argument because though Func<> has a covariant return type, it’s input argument generic types are contravariant. Similarly for a contravariant interface:
interface ITestContravariant<in T>
{
Func<T, bool> Foo1();
Action<T> Foo2();
}
Here, we have a contravariant parameter T, but we’ve indirectly used it in the return type by using it to set the contravariant parameters in the Func<> and Action<> delegates.
Tags: C#/.NET
The CLI supports variant generic parameters for interfaces as well as delegates, and C# 4.0 has added support for that. In this blog entry I’ll talk a little about variance in generic interfaces, and in a later entry I will talk about variance in delegates.
Covariance allows you to use a more derived type than what’s specified by the generic parameter, whereas contravariance allows you to use a less derived type. Generic interfaces can be covariant, contravariant, or both (though not for the same parameter).
Consider the following code:
class Base
{
}
class Derived : Base
{
}
interface ICovariant<out T> <-- covariant parameter
{
}
class Covariant<T> : ICovariant<T>
{
}
interface IContraVariant<in T> <-- contravariant parameter
{
}
class ContraVariant<T> : IContraVariant<T>
{
}
There’s a base class and a derived class, a covariant interface, an implementation of that interface, a contravariant interface, and its implementation. In C# a covariant parameter is prefixed with out, and a contravariant parameter is prefixed with in. In MSIL the symbols + and - are used for covariance and contravariance. (Note : at the time of writing, Reflector does not recognize or show variant generic parameters, but ildasm does show it correctly).
Here’s some code that shows the variance in action:
ICovariant<Base> baseCov = new Covariant<Base>();
ICovariant<Derived> derivedCov = new Covariant<Derived>();
baseCov = derivedCov; <-- covariance
IContraVariant<Base> baseContra = new ContraVariant<Base>();
IContraVariant<Derived> derivedContra = new ContraVariant<Derived>();
derivedContra = baseContra; <--contravariance
In the first case, we were able to assign a more derived generic instantiation to be assigned to a less derived one. In the second case we did the exact opposite. The Base Class Library has been updated to support covariance and contravariance in various commonly used interfaces. For example, IEnumerable<T> is now a covariant interface - IEnumerable<out T>. This lets us do:
IEnumerable<object> objects = new List<string>();
IEnumerable<Base> baseList = new List<Derived>();
That was something you could not do prior to C# 4.0. Now you won’t have to use LINQ’s Cast<>() as often as you may doing now. There are some rules to follow when using variant generic parameters.
For covariant generic parameters, the generic parameter can only be a return type, it cannot be used as a method argument. It also cannot be used as a generic constraint. (Note : A contravariant delegate can be used as a method parameter that uses the generic parameter as its generic parameter type. I’ll talk about it in my entry on variant delegates)
For contravariant generic parameters, the rules are basically reversed. The parameter type can only be a method argument or a generic type constraint, it cannot be used as a return type. Here’s an interface that has both contravariant and covariant generic parameters.
interface IContraAndCovariant<in T1, out T2>
{
T2 Foo(T1 value);
}
Here’s a more realistic example of where covariance comes in very handy:
class Item
{
public void CheckOut()
{
Console.WriteLine("{0} checked out", Code);
}
public int Code { get; set; }
}
class Book : Item
{
public string Title { get; set; }
}
static void CheckOutItem(IEnumerable<Item> source, int code)
{
try
{
source.First(item => item.Code == code).CheckOut();
}
catch (InvalidOperationException ex)
{
Debug.WriteLine(ex.Message);
}
}
CheckOutItem expects an IEnumerable of Item elements, but because IEnumerable<T> is covariant, I can do this:
List<Book> books = new List<Book>()
{
new Book(){Code = 99, Title = "C++/CLI in Action"},
new Book(){Code = 101, Title = "Ajax in Action"},
new Book(){Code = 105, Title = "ASP.NET Ajax in Action"},
};
CheckOutItem(books, 99);
I have passed an IEnumerable<Book> to a method where an IEnumerable<Item> was expected. And here’s a realistic example of where contravariance can be used:
class ItemComparer : IComparer<Item>
{
public int Compare(Item x, Item y)
{
return x.Code.CompareTo(y.Code);
}
}
private void ContravarianceTest()
{
List<Book> books = new List<Book>()
{
new Book(){Code = 199, Title = "C++/CLI in Action"},
new Book(){Code = 501, Title = "Ajax in Action"},
new Book(){Code = 105, Title = "ASP.NET Ajax in Action"},
};
books.Sort(new ItemComparer());
}
I used the List<T>.Sort overload that takes an IComparer<T> argument which in this case would have been an IComparer<Book> but since IComparer<T> is contravariant with regard to T, I could pass my ItemComparer class which is actually an IComparer<Item>.
Funnily, now that it’s available it’s kind of hard to think of how people managed to go without this all these years. It’s more the sort of feature that gets a “woah, we didn’t have this before!” response from people. In a later entry I will discuss variance in delegates.
Tags: C#/.NET
One commonly heard grievance about C# was how it did not support optional parameters. Well C# 4.0 not only has that, but you can also specify parameters by name.
Consider the following two examples :
public void RepeatText(string text, int count = 3)
{
while (count-- > 0)
{
Console.WriteLine(text);
}
Console.WriteLine();
}
public void RepeatDecoratedText(string text, string decoration = "Mr.", int count = 3)
{
while (count-- > 0)
{
Console.WriteLine("{0} {1}", decoration, text);
}
Console.WriteLine();
}
RepeatText has an optional parameter count with a default value of 3, while RepeatDecoratedText has two optional parameters. The MSIL generated for these methods are as follows (simplified, and not exact) :
.method public void RepeatText(string text, [opt] int32 count)
{
.param [2] = int32(3)
.method public void RepeatDecoratedText(string text, [opt] string decoration, [opt] int32 count)
{
.param [2] = string('Mr.')
.param [3] = int32(3)
[opt] is a parameter attribute that indicates that this parameter is optional and that the default value will be specified by .param entries. These methods can now be called as follows:
RepeatText("Nish");
RepeatText("Ant", 2);
The compiler generates code with the optional values filled in as needed:
RepeatText("Nish", 3); <-- 2nd param set via .param value
RepeatText("Ant", 2); <-- No extra work needed
You can also now pass an argument by name. This is particularly useful when you want to skip some optional args, but provide others.
RepeatDecoratedText("Nish", count: 2);
RepeatDecoratedText(count: 2, text: "Ant");
RepeatDecoratedText(decoration: "The super", count: 2, text: "Ant");
That gets compiled as:
RepeatDecoratedText("Nish", "Mr." 2);
RepeatDecoratedText("Ant", "Mr.", 2);
RepeatDecoratedText("Ant", "The Super", 2);
So basically, the parameters are either filled in via the named values provided or via the default optional values. Note that you can write optional value methods using attributes too. Example:
public void RepeatTextDuplicate(string text, [Optional, DefaultParameterValue(3)] int count)
{
RepeatText(text, count);
}
RepeatTextDuplicate("Nish");
RepeatTextDuplicate("Nishant", 5);
The MSIL generated for this method is identical to what you’d have got with the direct C# syntax (used earlier).
As with dynamic types, apparently the biggest beneficiaries of these new named and optional parameter features are developers who interop with Office. Just like in VBScript you can now avoid having to provide optional arguments, and can also provide a named argument directly. For others, optional parameters will definitely help reduce the number of method overloads you need to write, and where there are methods that have more than a few optional parameters, the ability to call them by specifying named parameters will result in cleaner and more legible code.
Tags: C#/.NET
VS 2010 Beta 1 includes some C# 4.0 features and though I have been reading about some of the new stuff on various blogs and forums, I only got to play with it very recently. Put simply, the dynamic keyword allows you to declare and use types that are not type-checked during compilation. They are resolved at runtime using the DLR.
Here’s a simple class that has a dynamic field, a method that has a dynamic argument, and a dynamic property:
class Dynamic
{
private dynamic data;
public void SetData(dynamic data)
{
this.data = data;
}
public dynamic MetaData { get; set; }
public void Display()
{
Console.WriteLine("{0} {1}, {2} {3}",
data, data.GetType(), MetaData, MetaData.GetType());
}
}
Using the class is quite straightforward:
private void Foo()
{
var d = new Dynamic();
d.MetaData = 100; <-- Int32
d.SetData(99); <-- Int32
d.Display();
d.MetaData = 100f; <-- Single
d.SetData("hello"); <-- String
d.Display();
}
Notice how I keep using different types at runtime for calling the same methods and properties. If you look at the IL via Reflector, you’ll see that dynamic types are internally treated as System.Object. Intellisense within VS 2010 will also give you System.Object members since that’s what they are guaranteed to have.
There are three dynamic calls in the Display method. A nested static class is generated inside the Dynamic class, and it will have one static CallSite<> field per dynamic call. In this case, there are three such fields. Whenever the dynamic calls are made, it’s these DLR call sites that come into play. An extremely simplified explanation of what happens is that the DLR internally uses reflection to figure out what type the dynamic object is at runtime. There is also caching done so that type-matching (or mapping) is not repeated unnecessarily. Of course the implementation is quite complex and you could probably spend weeks going through the code in Reflector. Note that if you make dynamic calls in a different method, there will be another static class generated - so it seems to be one inner class per method.
Consider the following simple method:
public void Test()
{
var type = data.GetType();
}
A class will be generated similar to the following (I’ve made this easy to read - so this is not an accurate representation of the generated code):
[CompilerGenerated]
private static class SiteContainerForTest
{
public static CallSiteobject, object>> callSiteGetType;
}
And the method Test gets compiled into:
public void Test()
{
if (SiteContainerForTest.callSiteGetType == null)
{
SiteContainerForTest.callSiteGetType = CallSite<Func<CallSite, object, object>>.Create(
new CSharpInvokeMemberBinder(
CSharpCallFlags.None,
"GetType", <-- the name of the dynamic member
typeof(Dynamic),
null,
new CSharpArgumentInfo[] { new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }
)
);
}
object type = SiteContainerForTest.callSiteGetType.Target(
SiteContainerForTest.callSiteGetType,
this.data <-- the dynamic object
);
}
The call site’s Target will be of type Func<CallSite, object, object>, and the return type is object (because at compile time that’s what the local variable type was defined as, since we don’t know what type it would be at that time). It’s at this point that dynamic binding is done. Fortunately for us, it’s all done behind the scenes and we are protected from having to write all this code ourselves. Assuming data is an Int32 at this time, Int32’s GetType is called (and since it doesn’t have one, Object’s GetType is invoked).
You can also use dynamic types locally (a site container class is generated for the containing method) :
dynamic d = 1;
string s = d.ToString();
Console.WriteLine(s);
d = "dynamic data";
Console.WriteLine(d.Length);
d = 33;
try
{
int len = d.Length; <-- Invalid dynamic call on an Int32 object
}
catch (RuntimeBinderException ex)
{
Console.WriteLine(ex.Message);
}
When I try to use the non-existent Length property on an Int32 value, the runtime will throw a RuntimeBinderException. And it even gives a very useful error message : ‘int’ does not contain a definition for ‘Length’.
Overall, one of the most celebrated uses of dynamic types is supposed to be for Office interop. You no longer have to do endless casts and mid-level variables for debugging. It’s just as easy as using classic VBScript. At this point, unless you want to interop with Word or Excel, I can’t think of too many scenarios where this will come in handy. Maybe someone who’s more functionally oriented than I am can think of some common scenarios.
Tags: C#/.NET · General
Here’s another tip from an MSDN forum discussion. Someone wanted to know how to flush the keyboard buffer in a C# console application.
Here’s a simple hack to do this :
private static void FlushKeyboard()
{
while (Console.In.Peek() != -1)
Console.In.Read();
}
Now you can use it as follows :
char x = (char)Console.Read();
FlushKeyboard();
char y = (char)Console.Read();
Console.WriteLine("{0}, {1}", x, y);
Even if you enter more than a single character after the first call to Read(), the second Read() will not be affected.
Tags: C#/.NET · General
A few weeks ago someone asked on the MSDN forums how he could use the mailto: protocol to send a multi-line email. The trick is to use %0D%0A in lieu of \r\n.
Here’s a small C# code snippet that shows how to do this :
string command = "mailto:abc@abc.com?subject=The Subject&body=Ln 1%0D%0ALn 2";
Process.Start(command);
Tags: C#/.NET
I just published an article on a generic Trictionary class :
The article describes a Trictionary class that is essentially a dictionary except that for each key there are two values, both of differing types. In many cases instead of doing this, the proper approach would most likely to use a struct that would have those two types as members. But there may also be scenarios where you may want to avoid having to unnecessarily create a struct just for this purpose. You could also use an anonymous type, but that’s really not so different in the sense you still end up having a new type in your assembly. Read the article for more info.
Note that the article was inspired by another Trictionary article on Code Project submitted by Joe Enos.
Tags: C#/.NET · CLR/.NET BCL
Someone was recently complaining in the MSDN forums that intellisense did not work for strings when it came to the Linq extension methods. If you are wondering what that’s about, System.String is an IEnumerable<char> so you can do all of the Where, Select operations on any string object. Here’s a contrived example :
string s = "What's cooking in Alabama?";
char[] vowels = new[] {'a', 'e', 'i', 'o', 'u'};
char[] nonVowels = s.Where(c => !vowels.Contains(
Char.ToLower(c))).ToArray();
Console.WriteLine(new string(nonVowels));
You just need to manually type in the method name (like Where) and once you do that you’ll then start getting intellisense. You just won’t get it for the starting string object. If you really want it there too, you can use an extra IEnumerable<char> variable and then use that instead of the string. Now you will get full intellisense.
IEnumerable<char> chars = s;
The String class is already equipped with a lot of useful methods, and there’s always the Regex class if you really need some complex string manipulation. So I am not sure there are too many scenarios where you’d actually want to use Linq with a string, but to each his own 
Tags: C#/.NET
Last week I attended the 2009 MVP Summit held at Redmond/Seattle and I’ve got to say that I had two rather peculiar experiences whilst there. The first incident was on the way to Seattle – it snowed in Atlanta of all things to happen and this resulted in dozens of cancelled and delayed flights. My flight was scheduled for a 2:30 PM departure and after a 3 1/2 hour delay where they pushed back the boarding time every 30 minutes, we finally boarded at 6 PM. Once we got in the aircraft we waited on the tarmac for another 3 1/2 hours more before take-off as we had to wait in line behind dozens of other flights for de-icing. I am still not sure why they couldn’t have us wait outside (at the gate) and let us board after the de-icing. The air was pretty stuffy inside because the air-conditioners seemed to be at half power. And after take-off they ran out of food when it was my turn to order - so yeah, that didn’t help either. It was one of the nastiest experiences I’ve had in an airport/flight in my entire life – one that I hope will not be repeated in future.
The second incident occurred on Tuesday night (or rather Wednesday morning). I was at the Grand Hyatt (17th floor) and had gone to bed close to 1 AM as I had gone for a late dinner/chat with an old friend. Around 4:30 AM or so this really loud siren came on and an even louder announcement was repeated instructing all occupants to move to the nearest staircase and to descend to the first floor immediately. It was also announced that the elevators were shut down. I wasn’t sure if it was a fire-emergency or some temporary air-pollution – in any case, I put on my shoes, picked up my laptop and climbed down the 17 set of stairs (16 maybe if they didn’t have a 13th floor, didn’t feel like counting then). I found a few dozen equally incredulous folks downstairs wondering what the heck had just happened. We watched the fire-trucks come and the firemen go up – and all this time we were all out on the streets. A few minutes later, they said everything was alright and said we could go back up to our rooms. There was a further wait of 20 minutes or so as we waited for an engineer to come down and reset the elevator system – and I didn’t want to climb up the 17 floors, not with my laptop. The worst part of the incident was when we found out that some dim-witted inconsiderate jerk had been smoking in a non-smoking floor which was what set off the fire-alarm. So they had to evacuate that floor as well as the floors directly above and beneath it.
The nice thing about the trip was that the summit was pretty good, we had some interesting technical sessions, the food was great, and it was good to catch up with some fellow MVPs and Microsoft buddies – some of whom I’ve only met at Microsoft summits and never outside Redmond.
Tags: General
February 26th, 2009 · 2 Comments
Once in a while you have people complaining in the forums that their .NET applications are not releasing memory but that if they minimize the app and restore it, then the memory usage goes down. Why this happens is explained in this Microsoft KB article :
You can simulate this in your code too (under extreme conditions when you really need the memory). In my case I had to do this in an app that loaded very large PNG files - once in a while we’d get a memory exception and then I’d call this method and retry and it would work. It does sound a bit hack-ish but there was nothing else we could do.
[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize",
ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
private static extern int SetProcessWorkingSetSize(
IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);
public static void ReleaseUnusedMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
SetProcessWorkingSetSize(
System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
I thought it’d be nice to post this here in case anyone else ever needs this.
Tags: C#/.NET · CLR/.NET BCL
February 25th, 2009 · 3 Comments
Recently in the MSDN Forums, someone wanted to know how he could use reflection to invoke a constructor that took a ref parameter. Personally I can’t think of any reason why a constructor would have a ref parameter, and try as I did I could not dig up that thread (neither Google nor MSDN forum search returns the right thread in the search results).
Anyway his main issue was that he did not know how to get the type of a ref string argument. C# will not let you do typeof(string&) which is what he wanted. The solution was to use Type.GetType("System.String&"). In case anyone ever has this bizarre requirement, here’s a small sample that shows how this can be done.
class A
{
public A(){}
public A(ref string id)
{
id = "AAA";
}
}
class B
{
public B(){}
public B(ref string id)
{
id = "BBB";
}
}
class Program
{
static void Main()
{
new Program().Foo();
}
private void Foo()
{
string s = "SSS";
Console.WriteLine(s);
Bar(typeof(A), ref s);
Console.WriteLine(s);
Bar(typeof(B), ref s);
Console.WriteLine(s);
}
private void Bar(Type type, ref string s)
{
var ctor = type.GetConstructor(
new Type[] { Type.GetType("System.String&") });
var arr = new object[] { s };
ctor.Invoke(arr);
s = (string)arr[0];
}
}
Note how I have to copy back the string from the object array. This is because while the string is passed by ref, it’s the reference in the array that’s passed to the constructor - and not the string that was passed as a parameter to the Bar method. The difference may be subtle unless you think about it.
Tags: C#/.NET
February 21st, 2009 · 1 Comment
I am writing this blog entry as a reminder to myself to be careful when using static fields or properties, and I wanted to document some silliness on my part for posterity. Recently I was working on some code where I wanted to keep track of derived class instances by storing them in a static list in the base class. The classes I was working on were non-trivial and fairly complex (and the original versions were not even authored by me). So for the sake of this blog entry, I’ve come up with simplified base and derived classes to explain what happened. Here’s what the base class looked like :
class Base
{
private static List list = new List();
public static List List
{
get { return Base.list; }
}
private Base()
{
Base.list.Add(this);
}
public string Name { get; private set; }
public Base(string name) : this()
{
this.Name = name;
}
}
And here’s what a typical derived class would be like :
class Derived : Base
{
public static Derived Nish = new Derived("Nish");
public static Derived Andrew = new Derived("Andrew");
public static Derived Megan = new Derived("Megan");
public Derived(string name) : base(name)
{
}
}
I thought it was all good, and then ran some code that did an iteration of the list :
foreach (Base item in Derived.List)
{
Console.WriteLine(item.Name);
}
To my tremendous surprise nothing came up and the list was empty. For a full 10 minutes, the idiot that I am, I kept pondering over this and wondering what the heck was going on. Then it hit me just like that. Even though I was accessing Derived.List, that was just a C# syntactic convenience that allowed me to write it that way because Derived did not have a List member at all (the compiler auto-fixes this to Base.List in the generated MSIL). The property was defined on Base, and thus Derived has not been accessed yet when I iterate Derived.List. So Derived’s static initialization has not even happened yet. Once I realized my folly, fixing it was straight forward, I had to bring down the List property to the Derived class. This meant that every derived class had to do that which was a bit of an annoyance but not so much as to be a show stopper. Here’s the correct code (for my simplified example) :
class Base
{
protected static List list = new List();
private Base()
{
Base.list.Add(this);
}
public string Name { get; private set; }
public Base(string name) : this()
{
this.Name = name;
}
}
class Derived : Base
{
public static Derived Nish = new Derived("Nish");
public static Derived Andrew = new Derived("Andrew");
public static Derived Megan = new Derived("Megan");
public Derived(string name) : base(name)
{
}
public static List List
{
get { return Base.list; }
}
}
Next time you are using static properties in your base classes, just be a little careful - I know I’ll be.
Tags: C#/.NET · CLR/.NET BCL
In my previous blog entry, I had recommended storing enums using their string representations when writing them to a database. There’s a caveat there though - the enum names should be guaranteed to remain stable, because if you change the name of an enum member, it breaks the database. For my specific scenario I ended up using enum values with explicit short values, so if the names ever change in future the short values remain the same and thus the database remains consistent.
There are other approaches to solving this too. Reader Arnaud Weil suggests having a table for each enum and the enum id from this table is used to refer to the enums elsewhere in the database. The guys at my current project have a specialized class that emulates enums and also allows the ability to associate meta-information to each enum value (like an image or a description). A third approach would be to use custom attributes and a type descriptor that’d extract the meta-information from an enum type. The old adage is true - there are many ways to skin a cat.
Tags: General
January 28th, 2009 · 3 Comments
I was reviewing some code and found that there were a few enum types that did not have a None value (which is a recommended practice). I thought I’d go ahead and add the None values when I found that the enum values were being written to the database via calls to Convert.ToInt32. Of course this meant that I could not add a None member as the first value since it’d break the database. If all of the enum members specified explicit int values I probably could still add a None member, but even that is kinda messy.
My recommendation is to store enums as strings in the database. Now you can change the order of the members, add and remove members etc. with absolutely no issues. Converting between an enum value and its string name is rather trivial too.
Tags: C#/.NET · CLR/.NET BCL
I’ve been using StyleCop for a few weeks now and after I got over the initial shock, I actually like using it now. In the long run, the big thing about using it is that your code looks consistent. Of course, in a small company it’s easy to get everyone to move to StyleCop, things may be a tad more difficult convincing a bigger group of people to do so.
Some of the rules may seem odd. For example, StyleCop will warn you if you do :
if(someCondition)
DoSomething();
You need to put braces around it as :
if(someCondition)
{
DoSomething();
}
Funnily I used to do this till a few years ago, then I started omitting the braces for single-line if-blocks because that’s what my colleagues did too. And now I’ve gone back to using braces. And yes the same rule applies for the else statement too.
I’ll be blogging more stuff on my StyleCop experiences. This post was just a quick something to break the bloggers-block that’s infected me the past few months.
Tags: C#/.NET
If you set a parent window’s Opacity, any child windows can only have an opacity equal to or below the parent window’s. So if you want to keep the main window background transparent but leave the child controls (such as a text box) fully opaque, it will not work as you expect. One solution (there are possibly others too) is to do the following.
Set the main window’s AllowTransparency to true and set the Background to Transparent.
<Window . . .
AllowsTransparency="True" Background="Transparent"
>
Now say you main panel is a grid, put a Border control on it as follows :
<Border Opacity="0.9" . . .>
<Border.Background>
. . .
</Border.Background>
</Border>
Set the border’s background to what you originally wanted the main window’s background to be. Now you’ll find a transparent window background where your editable controls can still retain 100% opacity.
Warning : Setting AllowTransparency to true on the main window potentially results in some very bad performance issues on both XP and Vista since WPF switches to software rendering (in my experience, even with good video cards). Once that happens, animations and video can get pretty unusably slow.
Tags: Avalon
Last week at work, I had to work on a C++/CLI class that derived from a class written in C# which implemented IDisposable. I got it wrong at first (yeah, same guy who wrote a book on the subject a couple of years ago) and my boss and I spent some time going through the generated code in Reflector before fixing it up. I came home that night and quickly put together a simple project so I could see the whole picture from a simple perspective. I thought it would benefit others to put together an article reflecting (no pun intended) the issue.
Tags: C++/CLI