January 14, 2010 at 11:34 AM · Filed under development
Or: Unavailability of value comparison of objects in .NET, a technical or philosophical restriction?
I was working on unit tests and then a question came to me – why comparing objects by value is not provided out-of-the-box by the .NET Framework? We all (should) know that by default, comparing objects leads to a reference comparison, unless of course you override Equals() or implement operator == on your class.
But what if I want to compare two objects from a class provided by the Framework? That would be quite handy specially for unit tests. While we have System.Object.Equals() and System.Object.ReferenceEquals() working the very same way – reference comparison – we don’t find something like System.Object.ValueEquals().
Then I started having a discussion with a friend and colleague of mine the reasons for such functionality not existing in .NET.
Although I agree that the default option should be reference comparison, I don’t see any technical limitations for not having that implemented – Reflection could be the way to do it, going recursively down each property and checking if their values are equal.
So why not? Is it something related to the theory of object orientation or was it a mere technical decision?
Let’s take one of the classical examples of OO lessons: a Car class. In a Car, you have properties such as Color, Model, Category, etc. In real life, when two cars come out of production line, while you can’t say they are the same car, one would have no problem identifying they were built by the same method. Just compare each of their properties and you will end up knowing they are not the same car, but they share the same properties and were built the same way. They don’t share a reference equality, but value equality.
As far as I am concerned, OO does not provide a specific way or method to apply the property-by-property comparison, but there isn’t a prohibition on doing that as well.
However, providing such functionality could be an expensive trade-off, since gigantic objects with collections with millions of items could be compared. It would be possible, but sometimes not practical. But then not providing that for the developer’s discretion, or at least providing ways to ensure it could be safely used? Doesn’t seems right to me.
From my point of view, such functionality could be very useful and there is no true restriction that should be applied for having something like that provided by the Framework. As I said, my opinion is that not providing it is a technical decision, and not a philosophical restriction imposed by OO theory.
What do you think? I’d be glad to listen to other opinions!
Ouvindo: The Real McKenzies – Scots Wha' Ha'e
January 8, 2010 at 4:40 PM · Filed under development
Although I’ve worked with WWF (Windows Workflow Foundation) during all 2009, I haven’t posted anything about the technology yet, so I thought it was maybe the time to do it. I’ll start with one of the bases of the implementation of custom ActivityValidator classes. Despite being simple, that is an error that strikes new workflow developers quite often.
When creating a custom ActivityValidator, you might receive a compilation error from the newly created validator, even when the custom Activity it is targeted against is not in use yet.
But how come? Let’s take a look at the example below:
[ActivityValidator(typeof(MyCustomValidator))]
public partial class MyCustomActivity : Activity
{
public static DependencyProperty PriceProperty = DependencyProperty.Register("Price", typeof(float), typeof(MyCustomActivity));
[DescriptionAttribute("Price")]
[CategoryAttribute("Price Category")]
[BrowsableAttribute(true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public float Price
{
get
{
return ((float)(base.GetValue(MyCustomActivity.PriceProperty)));
}
set
{
base.SetValue(MyCustomActivity.PriceProperty, value);
}
}
public MyCustomActivity()
{
InitializeComponent();
}
}
public class MyCustomValidator : ActivityValidator
{
public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
{
MyCustomActivity myCustomActivity = obj as MyCustomActivity;
ValidationErrorCollection errors = base.Validate(manager, obj);
if (myCustomActivity == null)
{
throw new ArgumentException("MyCustomValidator can only be used to validate MyCustomActivity instances.", "obj");
}
if (myCustomActivity.Price <= 0)
{
errors.Add(new ValidationError("'Price' must be greater than zero.", 1));
}
return errors;
}
}
In the example above, when you build the project you will receive an error such as
Error 1 Activity 'MyCustomActivity' validation failed: 'Price' must be greater than zero.
Well, that is not nice. You are not even using MyCustomActivity yet!
The reason for that is simple: validators are run during runtime, but also during build time! To avoid the error, we simply check if the custom activity is in use. How? Take a peak:
public class MyCustomValidator : ActivityValidator
{
public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
{
MyCustomActivity myCustomActivity = obj as MyCustomActivity;
ValidationErrorCollection errors = base.Validate(manager, obj);
if (myCustomActivity == null)
{
throw new ArgumentException("MyCustomValidator can only be used to validate MyCustomActivity instances.", "obj");
}
if (myCustomActivity.Parent != null)
{
if (myCustomActivity.Price <= 0)
{
errors.Add(new ValidationError("'Price' must be greater than zero.", 1));
}
}
return errors;
}
}
As you can see, all we did was checking if the activity parent is not null (line 13).
Try to build now, no error will be triggered. Then drop MyCustomActivity to a workflow, don't fill in Price and build again. The error is now there, correctly returned!
Well, that was it... No black magic but surely resourceful! I hope it helps!
Ouvindo: Cólera – Vira-Latas
May 25, 2009 at 10:06 AM · Filed under nerds
You are here. You are a nerd. And you are proud of that.
Be happy, today is our day! Happy Nerd Pride Day!
Ouvindo: Twoface – Road Rage (Live)
April 17, 2009 at 5:15 PM · Filed under development
You are coding an UserControl for your Silverlight 2 application that might change the world. You are almost done with it, already told all the guys that the first round is on you. You are thrilled about your fabulous coding skills.
And then you find him. An horrendous, terrible, dreadful enemy. His name: AG_E_PARSER_UNKNOWN_TYPE.

You start looking for reasons of such an error, but all you find is despair. No hints, no clues, you start loosing your temper – and possibly your hair. You curse the framework for not supplying you with enough information: just a plain AG_E_PARSER_UNKNOWN_TYPE on your xaml file. Googling does not help you much, as few have faced that horrible vilain.
Fear not, friend, as I have found him myself, and I am going to share the secrets of some of his weak spots. Explore them, and I hope you defeat him the way I did.
Jokes apart, that was an error that took me a while to figure it out. Everything happened when I was creating user controls that were related to each other by their parent class. And impressively I run into two different situations in the same task that lead me to AG_E_PARSER_UNKNOWN_TYPE.
My solution was structured as follows:
using System;
using System.ComponentModel;
namespace MySolution
{
public abstract class MyBaseClass : UserControl
{
}
public partial class MyClass1 : MyBaseClass
{
}
public partial class MyClass2 : MyBaseClass
{
}
}
First error in the intended code above: the MyBaseClass derivating from UserControl can’t be declared abstract. I know, it is a pain in case you want to create an abstract method within – you won’t be able to do that at all. Try a workaround like creating virtual methods throwing a NotImplementedException, and then overriding it with the real implementation.
The other situation I found that error in was related to listeners and the user control constructor. I’m not entirely sure why that happens, but if you register for a listener on the constructor class (or call any method registering it from the constructor) of your user control, you might have a chance to encounter the might evil AG_E_PARSER_UNKNOWN_ERROR is.
Also, a collegue pointed out for me a blog post with some explanations to AG_E_PARSER_UNKNOWN_ERROR and other Silverlight hell minions alike. Despite being related to Silverlight 1.1 alpha, I found the list to be trully helpful. I wish I had found that one before, the struggle would be much smaller!
Ouvindo: Deluxe Trio – Mais Pimenta Menos Sal
February 15, 2009 at 10:08 AM · Filed under development
Today I had a nice learning experience on how to handle “please wait” screens and asynchronous calls on Silverlight 2.
Say that you want to present a message to your user while he waits an asynchronous call to be completed. However, given the nature of the call, you can’t control how long it will take to complete, and thus that message may be just a quick blink in the screen. But what if you still want that message to be readable, even when the call answers almost instantaneously?
Using System.Threading.Thread.Sleep() is not a good option, since it will hold the current thread – that is, the UI thread. And the user will be probably pissed off for having his browser frozen by the application.
The solution: BackgroundWorker and Dispatcher classes.
System.ComponentModel.BackgroundWorker (MSDN link) is a class that allows instructions to be run on a dedicated thread, with support to cancellation and progress reporting, while Dispatcher (MSDN link) is a handy property from the UserControl class (the one used as a base class to Silverlight pages) that gives us access to the UI thread.
Let’s see a simple example on how to implement the proposed solution.
using System;
using System.ComponentModel;
using System.Threading;
public class Page : UserControl
{
// Bogus is any given class with an asynchronous call
private Bogus bogus;
private BackgroundWorker bgWorker;
public Page()
{
InitializeComponent();
// Creates the BackgroundWorker and says it supports cancellation
bgWorker = new BackgroundWorker();
bgWorker.WorkerSupportsCancellation = true;
// Registers the listener
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
// Instantiate the class that runs the asynchronous call
bogus = new Bogus();
}
#region Button handlers
private void btnCallAsync_OnClicked(object sender, EventArgs e)
{
// Registers the listener for handling the result for the asynchronous call
bogus.BogusCompleted += new BogusEventHandler(bogus_BogusCompleted);
// The "please wait" message
lblText.Text = "Please wait while operation is processed...";
// Run the BackgroundWorker thread
bgWorker.RunWorkerAsync();
}
// Handles cancelation of the asynchronous call
private void btnCancel_OnClicked(object sender, EventArgs e)
{
// Let's unregister the listener so that the asynchronous call
// result is not handled
bogus.BogusCompleted -= new BogusEventHandler(bogus_BogusCompleted);
// Removes the "please wait" message
lblText.Text = string.Empty;
// Cancels the BackgroundWorker thread
bgWorker.CancelAsync();
}
#endregion Button handlers
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Let's run it unless the BackgroundWorker is pending
// cancelation
if(!bgWorker.CancellationPending)
{
// CurrentThread is not UI thread, since we are inside
// BackgroundWorker thread
Thread.CurrentThread.Sleep(new TimeSpan(0, 0, 3));
// After sleeping for some time to allow users to read
// the message, we start the asynchronous call
bogus.RunBogusAsync();
}
}
private void bogus_BogusCompleted(sender object, BogusEventArgs e)
{
// Any operations you want to execute in the UI thread
// as a result of the asynchronous call
Dispatcher.BeginInvoke(() => { UIOperations(); });
// Unregister the listener since the call was already processed
// and it is registered back on btnCallAsync_OnClicked()
bogus.BogusCompleted -= new BogusEventHandler(bogus_BogusCompleted);
}
}
So now let’s see in detail what the above code does.
The xaml file includes three controls: lblText (TextBlock control), btnCallAsync and btnCancel (Button controls).
As shown on btnCallAsync_OnClicked() (lines 27 to 37), lblText will display the wait message when btnCallAsync is clicked. Additionally, it will register the listener for BogusCompleted event and trigger the execution of the background worker.
bgWorker_DoWork() (lines 54 to 68) will then sleep the BackgroundWorker thread for a while and finally call the asynchronous method RunBogusAsync() which we were originally interested in.
On BogusCompleted, bogus_BogusCompleted() (lines 70 to 79) is finally run and Dispatcher.BeginInvoke() is called (using lambda expressions) to run something on the UI thread. We also unregister the listener for BogusCompleted events, since it is registered back every time btnCallAsync is clicked.
Sure we have a problem in this approach: we sleep the thread for some seconds before calling the asynchronous call, and that might cause a long wait in case Bogus.RunBogusAsync() takes too long to execute. For example, if the asynchronous call took five seconds to complete, we would keep the user waiting for eight seconds.
As an exercise, put the BackgroundWorker thread to sleep after the call to Bogus.RunBogusAsync(), and only if the asynchronous call didn’t take more than three seconds, so that the total wait would be at least three seconds, but no unnecessary extra time when.
Ouvindo: Deluxe Trio – Meu Mundo
Next entries »