.net framework 2.0 introduced several great features which made a life easier for us developers a lot. One such feature is generics. The feature is closer to C++ templates but it has runtime type substitution compared to C++ templates which takes place at compile time. There are other differences too. This post is not about the introduction of the feature but this is about a limitation of the feature and possible workaround. The greatest read about the feature introduction can be found here:
http://msdn.microsoft.com/en-us/library/512aeb7t
Let's introduce an type which can be used to guard the parameters of a method. We will be adding specialized methods which can be used to verify if the argument fulfills certain parameter constraint. If not, generally an exception is thrown. We will be adding the flexibility to provide additional methods where we can just check the value rather than causing an exception.
We can use this Guard type as follows:
The developers who go back and forth between java and C# miss / appreciate the missing feature of throws for C# method. They miss them because there is no compile time support to check whether a possible exception is handled gracefully. They appreciate it because there are no handcuffs to handle exception which they don't want to. It also results in better versionability and scalability. Anders Hejlsberg has discussed in detail in this interview why they decided not to provide this feature in C#.
http://www.artima.com/intv/handcuffs.html
Now we come back to the topic and discuss what the above code does. As discussed it provides to methods. The actual verification code is provided by the client code because they better know what and how to verify. We just need to execute the code they provide. The constraint about verification code is that it must return a boolean. If verification fails then an exception is generated. The type of the exception would be the based on the type argument used with ArgumentGuard.
We are definitely the happiest developers in the world because we are able to provide an implementation which is simple and generalized. The client code not only would specify what and how to verify but it would also specify what exception should be resulted if the check in their own code fails. It's just like going to subway and choosing your options. This is exactly what they say, Tell me how do you want your sandwich. The only thing is that they don't let us make it ourselves and I don't forgive them for this mean attitude :).
The problem happens when one of the client developer shows up at your desk and requires the support of a particular exception message. That shouldn't be a big deal, we can just use the ArgumentException constructor which supports a message parameter. This might be the first thought which might come to your mind.
Well I have a bad news if you haven't got the issue with the above code. It seems that the compile doesn't like this and pukes this on us.
MSDN has details about the list of constraints possible with Generic Types [http://msdn.microsoft.com/en-us/library/d5x73970%28v=vs.100%29]. So you wouldn't be able to create an exception instance by using one of the constructor of ArgumentException which supports the parameter. The developer mindset puts us to bypass this limitation by this approach:
This approach works most of the time as we are bypassing the type argument constructor constraint by using the legal parameterless constructor. The type argument's type constraint lets us sets the property and doesn't seem to mind. But this is also not possible in this case as the Message property is read-only...Damn!!!
Am I still alive? A non-dead person always has some options in even the most desperate situation. Since we seem to be stuck here, we might ask this question to ourselves. But actually we haven't run out of options yet. One option is to get rid of the idea of using generics at all for this feature. Why should we use a language feature which doesn't support something that we actually need. Since there are only a few child classes of ArgumentException. This shouldn't be a big deal. We can make client's life easier by naming them as such that these types appear together in the intellisence so that client can make better decision about which ArgumentGuard he needs to use.
An evil developer still has some arrows to shoot. Let me say this and then we will use it, "We can set the value of a read-only field through reflection". Feels light once you let it out, right? So what if we set the Message using reflection, it should be fine. Just sneak it by avoiding the crappy purists like myself and you should be fine :(
Thanks God that it wouldn't work. Stupid myself, Message is not a field rather it is a property with no setter at all. It's not like that there is a setter but it is private. There is none whatsoever. We can use dotPeek to peek the definition of the type. It is overriding the Message property from its parent type but still providing no setter. Had there been a private setter, it would have worked like a charm.
So we can't set Message because it just has getter and no setter. Can we use the backing field for this property? In the base class in the hierarchy, eventually it is backed by _message field in System.Exception. On the way, to Argument's children, Message is overridden a few times but if we don't change anything else then the code below should work most of the times.
Since _message is an internal field in mscorlib assembly, we needed to use relevant BindingFlags to access the field. Now we can update the client code as follows:
In the above code, the verification criteria demands that a must not be null. Since the type argument is ArgumentNullException, it is expecting an ArgumentNullException with the appropriate message set. Let's try calling the method with null argument and test if it works as expected.
Now when we run it we do get the appropriate exception with the exact message as expected.
Hmm, this is working as expected. We are able to use generics for argument guard. We are also able to provide the expected exception message. But can you really call it a good design. Poking our noses into others private and internal members is never a recommended approach. The API owner is free to change the internal implementation as much and as often. As long as they are not changing the public behavior of types, they are not the one to blame if something in our code breaks just because they changed their internal implementation.
But is there really a way out? Aren't we stuck? We can't set the Message property (no setter constraint) and we can not use parameterized constructor (generics constructor constraint). It's time to take a step back and see do we really need to instantiate the Exception in Verify method. We just need to make sure that the exception is generated with appropriate message. What if we turn the table around and ask the caller to provide us the exception instantiation code. We will be generating the exception as provided to us by the caller himself. We don't need to set any property because it is now caller's responsibility to provide us with appropriate object with all properties set. If required, we will be executing the code provided by caller. There are no memory issues as the object is constructed only when required. This code would provide us the relevant exception object and we will be throwing that exception. Here we can constraint the type of exception based on the same type argument. Let's provide an overload of the same Verify method.
Now we can use the above guard argument helper as follows:
Now let's run the code again and see how it works.
Zindabad!!!
Download Code
Showing posts with label visual studio 2011. Show all posts
Showing posts with label visual studio 2011. Show all posts
Sunday, May 27, 2012
C# Generics Constructor Constraint & Guarding Arguments
Wednesday, April 18, 2012
Hello, this is C# method. Who is Calling me?
And there was no easier answer other than going through the stack trace and scanning the frames yourself. Well this is just made easier in Visual Studio 2011 Beta and we will be discussing the same feature today. This provides a method details about the caller.
Why should I care?
It seems that you haven't been involved in chasing and tracing some weird flow in which your code is executed. This has always been a pain for most of us. Sometimes, the only option left is to write a bunch of Trace.WriteLine() with some text to identify the method. Then at the end of usecase, you look at the trace to find out exactly what was the flow of execution of your code. This feature is provided to further support this tracing, debugging and diagnostics.
What Information does it provide?
This is an optional details that you can add to all or some of your methods. With the new features, you can get the following information easily:
This feature is supported by providing new attributes in System.Runtime.CompilerServices namespace in mscorlib.
How can I use them in my C# code?
These attributes are targeted for methods. We need to decorate the parameters with any of these attributes and the run-time would populate them with the relevant information as promised. This is built on top of another great C# feature. It is called optional parameters. This would have all the limitations of optional parameter i.e. these parameters must be the last parameters of the methods and they should have some default values assigned based on their types. CallerMemberNameAttribute and CallerFilePathAttribute may be assigned a string value. CallerLineNumberAttribute must be specified with some integer value.
Let's create a C# console application and update Program.cs as follows:
Here we have used all three of the newly available attributes in CallerInfoMethod definition. We are calling the method from within the same class from Main method. Let's run the application and see what it prints on the console.
Can I use more than One Attribute for a Parmeter?
I don't know why you would do that but you might be a bigger creative thinker than me. You might want to combine the information from those attributes. So to answer that, Yes you can use CallerFilePathAttribute and CallerMemberNameAttribute with the same parameter. They cannot be used with CallerLineNumberAttribute because of different data types. But the information is not combined instead, as I have noticed, CallerFilePathAttribute takes precedence and overrides CallerMemberNameAttribute. Let's update the same method as follows:
When we run the above code, we notice this override behavior:
Possible Improvement
I have seen most of the developers shooting down any and all ideas which involve System.Runtime.CompilerServices, and there is a reason for that. This is based on Microsoft's recommendation:
The classes in System.Runtime.CompilerServices are for compiler writers' use only.
I don't buy to this and clearly we use other things from the namespace too, like when unit testing InternalsVisibleTo is used very often. I think that it would be better if these new attributes are moved to System.Diagnostics instead. This should keep everyone happy.
Microsoft Zindabad!!!
Why should I care?
It seems that you haven't been involved in chasing and tracing some weird flow in which your code is executed. This has always been a pain for most of us. Sometimes, the only option left is to write a bunch of Trace.WriteLine() with some text to identify the method. Then at the end of usecase, you look at the trace to find out exactly what was the flow of execution of your code. This feature is provided to further support this tracing, debugging and diagnostics.
What Information does it provide?
This is an optional details that you can add to all or some of your methods. With the new features, you can get the following information easily:
- The compile time path of the source file of the caller.
- Line Number in the source file where the method is called
- The name of member [Property or Method] of the caller.
This feature is supported by providing new attributes in System.Runtime.CompilerServices namespace in mscorlib.
How can I use them in my C# code?
These attributes are targeted for methods. We need to decorate the parameters with any of these attributes and the run-time would populate them with the relevant information as promised. This is built on top of another great C# feature. It is called optional parameters. This would have all the limitations of optional parameter i.e. these parameters must be the last parameters of the methods and they should have some default values assigned based on their types. CallerMemberNameAttribute and CallerFilePathAttribute may be assigned a string value. CallerLineNumberAttribute must be specified with some integer value.
Let's create a C# console application and update Program.cs as follows:
Here we have used all three of the newly available attributes in CallerInfoMethod definition. We are calling the method from within the same class from Main method. Let's run the application and see what it prints on the console.
Can I use more than One Attribute for a Parmeter?
I don't know why you would do that but you might be a bigger creative thinker than me. You might want to combine the information from those attributes. So to answer that, Yes you can use CallerFilePathAttribute and CallerMemberNameAttribute with the same parameter. They cannot be used with CallerLineNumberAttribute because of different data types. But the information is not combined instead, as I have noticed, CallerFilePathAttribute takes precedence and overrides CallerMemberNameAttribute. Let's update the same method as follows:
When we run the above code, we notice this override behavior:
Possible Improvement
I have seen most of the developers shooting down any and all ideas which involve System.Runtime.CompilerServices, and there is a reason for that. This is based on Microsoft's recommendation:
The classes in System.Runtime.CompilerServices are for compiler writers' use only.
I don't buy to this and clearly we use other things from the namespace too, like when unit testing InternalsVisibleTo is used very often. I think that it would be better if these new attributes are moved to System.Diagnostics instead. This should keep everyone happy.
Microsoft Zindabad!!!
Wednesday, December 21, 2011
WPF 4.5 Developer's Preview - Delay Binding
In this post, let's discuss one great feature of Binding as in WPF 4.5 Developer's preview. This feature is called Delayed Binding. As a XAML technologies developers we are specially concerned about the timing when the values are copied between SOURCE and TARGET of binding.
From the very early stages, human has tried finding answer of this question. Who am I? Even famous eastern poet Bulleh Shah explained in one of his master piece.
Not a believer inside the mosque, am I Nor a pagan disciple of false rites Not the pure amongst the impure Neither Moses, nor the Pharoh Bulleh! to me, I am not knownSince WPF / Silverlight has very sophisticated Binding, the difference between Source and Target is blurred. Now the main question is what should be called Source and what should be considered as Binding Target. Although the question is not a philosophical one but we clearly need a way to identify the source and target of Binding. Charles Petzold makes it easier by calling Binding Target to be the one where the Binding is actually defined. Now the other party becomes the Binding Source. So if TextBox.Text is bound to FirstName property of the DataContext then TextBox.Text becomes the Binding target and hence DataContext.FirstName might be taken as Binding source. From Target to Source, we control the timing by using UpdateSourceTrigger property of Binding. As we know that it has three possible modes. PropertyChanged, LostFocus and Explicit. From Source to Target, this flow of update happens based on the nature of Source property. Generally, the view models implement INotifyPropertyChanged interface. Now setting the property causes PropertyChanged event to be raised. Binding Target listens to this event and update itself. The event has the details which property of the DataContext is updated which makes it easier for the runtime to update the view. The source property might be a DependencyProperty. As we know one of the feature of DependencyProperty is change notification. As WPF runtime receives such notifications, it propagates these changes to the Binding system, which causes updating the target's value.
The direction of flow of these updates are controlled by Binding mode. Different XAML technologies can have different default mode of binding. There are three different Binding modes in WPF / Silverlight. These Binding modes are as follows:
- TwoWay
- OneWay
- OneTime
- OneWayToSource
- Default
namespace MVVMDelayedBinding
{
using System.ComponentModel;
class MainWindowViewModel : INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
Since this is a WPF 4.5 Developer's Preview feature, we need .net framework 4.5 installed on the machine. We also need Visual Studio 11 Developer's Preview. Let's open this in the IDE and update the framework to .net framework 4.5.
Now let's update MainWindow.xaml as follows:
<Window x:Class="MVVMDelayedBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MVVMDelayedBinding"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.20*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Background="Navy" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" >
<TextBlock Text="Personal Information" Foreground="White" FontSize="20"
TextAlignment="Center" FontWeight="Bold" VerticalAlignment="Center"/>
</Border>
<Label Content="First Name" Grid.Row="1" Grid.Column="0" Margin="2,3,2,2"/>
<TextBox Grid.Row="1" Grid.Column="1" Margin="2,3,2,2" >
<TextBox.Text>
<Binding Path="FirstName"
Mode="OneWayToSource"
UpdateSourceTrigger="PropertyChanged"
Delay="200" />
</TextBox.Text>
</TextBox>
<Border BorderBrush="Silver" BorderThickness="1"
Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2">
<TextBlock Text="Other Details" TextAlignment="Center"
VerticalAlignment="Center"
FontSize="20"/>
</Border>
</Grid>
</Window>
This is simple example of MVVM based view. We are using the new MainWindowViewModel instance as the DataContext of the view. The most interesting thing is the TextBox Binding. We are binding the TextBox with FirstName property from the DataContext. The mode is set as OneWayToSource supporting the flow of value updates only from Target to Source. The UpdateSourceTrigger is set as PropertyChanged, resulting in the updates in the Target properties to be copied to the Source without waiting for losing the focus. Now look at the Delay. We are setting the delay as 200. This is in milliseconds. It means the runtime should wait for 200 ms to copy a property update to the Source. This would throttle fast changes to the view and wait for the interaction to get settled before the view state gets updated. Let's run this and use the First Name as Muhammad. Instead of the regular behavior of PropertyChanged. It throttled my input, waited for 200ms and updated the view model's property. This is perfect!
Download:
Labels:
.net,
.net 4.5,
binding,
C#,
databinding,
delay,
MVVM,
visual studio 2011,
wpf
Subscribe to:
Posts (Atom)












