Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

Everyday's Software Design

Scribbles on Software Engineering

Δεκέμβριος 2010 - Δημοσιεύσεις

Correctly Implementing Equals() in C#
 
It's said that "the devil is in the details". Well I saw some code the other day that reminded me exactly that quote. It is quite common for developers to forget about semantics. In my current project we tend to play a lot with Nhibernate and DDD and we seriously take care of our model. We take it to the extreme where we use every possible aspect defined in DDD, with Components being on of them. It is quite crucial to be careful when dealing with Components especially if ones uses them in a Set. Sets (as know from high-school math) are structures that can have only one instance per object. So we need to be sure that two objects are equal when we try to insert something to our Set (and respectively to the DB.)

I will try to show here the complete implementation of a class that needs to override Equals() as it should be. First we have to remember that in C# the semantics of equality define that two reference-objects are equal if the respective references point to the same object (aka object identity). Well, some people tend to forget that...

Here is how one should implement an object that needs to define its own version of Equals.

public class Foo : IEquatable<Foo>
{
public override bool Equals(Object right)
{
// check null:
// this pointer is never null in C# methods.
if (Object.ReferenceEquals(right, null))
return false;

if (Object.ReferenceEquals(this, right))
return true;
 
if (this.GetType() != right.GetType())
return false;
return this.Equals(right as Foo);
}
#region IEquatable<Foo> Members
public bool Equals(Foo other)
{
// Do your magic here...
return true;
}
#endregion
}

So what is going here? First things first:
Remember that .NET defines two versions of Equals:
public static Boolean Equals(Object left, Object right);
public virtual Boolean Equals(Object right);

Why don't we just use the static method Object.Equals? Well this method will do it's job only if both instances (this and right) are of the same type. That is because the static Equals all it does is a nullability check of both ends and then delegates the equality decision to the instance method Equals method. This is why we actually need to override the instance method and we NEVER touch the static method.

Another thing to note is that Equals should never throw any exception. It just doesn't make much sense. Two variables are or are not equal; there’s not much room for other failures. Just return false for all failure conditions, such as null references or the wrong argument types. Now, let’s go through this method in detail so you understand why each check is there and why some checks can be left out. The first check determines whether the right-side object is null. There is no check on this reference. In C#, this is never null. The CLR throws an exception before calling any instance method through a null reference. The next check determines whether the two object references are the same, testing object identity. It’s a very efficient test, and equal object identity guarantees equal contents. The next check determines whether the two objects being compared are the same type. The exact form is important. First, notice that it does not assume that this is of type Foo; it calls this.GetType(). The actual type might be a class derived from Foo. Second, the code checks the exact type of objects being compared. It is not enough to ensure that you can convert the
right-side parameter to the current type (inheritance bugs can surface if you go this way).

Finally we check if the two instances are of the same type and finally we delegate the decision to the type-safe implementation of Equals that is coming from the IEquatable interface. Overriding Equals() means that your type should implement IEquatable<T>. IEquatable<T> contains one method: Equals(T other). Implemented IEquatable<T> means that your type also supports a type-safe equality comparison. If you consider that the Equals() should return true only in the case where the right-hand side of the equation is of the same type as the left side, IEquatable<T> simply lets the compiler catch numerous occasions where the two objects would be not equal. There is another practice to follow when you override Equals(). You should call the base class only if the base version is not provided by System.Object or System.ValueType.

There are a few other rules that apply to value types but they are beyond the scope of this post which is already huge I think. One last not though just to make sure we all understand where all these semantics and practices come from. Math 101, the base of all our computer lives:


Equality is reflexive, symmetric, and transitive. The reflexive property means that any object is equal to itself. No matter what type is involved, a == a is always true. The symmetric property means that order does not matter: If a == b is true, b == a is also true. If a == b is false, b == a is also false. The last property is that if a == b and b == c are both true, then a == c must also be true. That’s the transitive property. This is common knowledge to every developer, so please try to meet their expectations (even the simpler ones) you handle some code to them ;)

WPF Metro Window

"Metro is an internal code name for a typography-based design language created by Microsoft. It was created as a product of Microsoft's user interface design work on some of their media products like Zune and Windows Media Center, for major utilization in their mobile operating system, Windows Phone 7", wikipedia.org


Continuing with Metro UI I will try to give here a bunch of information that seems to be quite scattered around the web and I will show how easy it is to build a sample window (no resizing) with WPF which will look like Metro.

The first place one should study is the official guidelines of Microsoft. There you will find all the documentation you need about the logic of Metro, design guidelines and Photoshop templates of icons, buttons etc. There is however a better alternative for the icons. Here you can find all the standard Metro UI icons in one zip all in png format, ready to use in your project.

A few other really interesting projects that apply the Metro UI are the following:
http://metrotheme.codeplex.com/
http://nroute.codeplex.com/
http://chronoswpf.codeplex.com/

Another important aspect of the UI in order to look proper has to do with the fonts. In most projects you might find styles that refer to the Segoe WP (from Windows Phone) fonts. While these fonts are also available for your PC and can be easily installed (either standalone or through the WindowsPhone tools) you should avoid it when you are building a WPF application. Segoe UI or Segoe Light render much better, especially for small sizes (below 15).

So going back to our sample window, we will build a simple WPF project from visual studio, and we will make our MainWindow look like a Metro one. Our window's xaml should look something like that:
<Window
x:Class="WpfMetroWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="470"
Width="900"
IsTabStop="False"
AllowsTransparency="True"
Background="{x:Null}"
BorderBrush="#FF3F3F3F"
PreviewMouseMove="HandlePreviewMouseMove"
SnapsToDevicePixels="True"
TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="ClearType"
ResizeMode="NoResize"
WindowStyle="None"
WindowStartupLocation="CenterOwner">
...

So with a no border, no resize, white and transparent window we are ready to begin. The next step is build the shadow around the edges. This can be accomplished easier that one might think. All we need is a border with the dimensions of our window which will have a shadow effect on it.
<Border
x:Name="m_edgeBorder"
x:FieldModifier="private"
Margin="10"
Background="White"
IsHitTestVisible="False"
IsEnabled="False">
<Border.Effect>
<DropShadowEffect
Opacity="0.999"
BlurRadius="16"
ShadowDepth="0" />
</Border.Effect>
</Border>

But since we have the window with no border we have two important issues: we have to find a way to move (drag) the window around and find a button that will close the window. For the first problem we create a rectangle on the top of the window and we attach to it's PreviewMouseDown event.
<Rectangle
Height="28"
VerticalAlignment="Top"
Fill="White"
PreviewMouseDown="HandleHeaderPreviewMouseDown" />
and then we have
private void HandleHeaderPreviewMouseDown(
Object sender,
MouseButtonEventArgs e)
{
m_headerLastClicked = DateTime.Now;
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
DragMove();
}
}

Now for closing the window we create a button with a custom style (we could also create a button template and give it one of the Metro png files we downloaded earlier).
<Button
HorizontalAlignment="Right"
Margin="500,6,8,0"
VerticalAlignment="Top"
Style="{StaticResource ChromeButtonStyle}"
Click="HandleCloseClick">
<TextBlock
TextWrapping="Wrap"
Text="r"
FontFamily="Webdings"
Foreground="#FF919191"
FontSize="13.333" />
</Button>
I know I've chosen a really weird way of showing the "X" on the close button but trust me it works. Here's a sneak peek.

What I finally added, as I wanted my window to work with Caliburn.Micro, is a ContentControl which will host all the screens into this "shell" window.
<ContentControl
x:Name="ActiveItem"
Background="Transparent"
HorizontalAlignment="Stretch"
IsTabStop="False"
Focusable="False"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
VerticalAlignment="Bottom"
Margin="13,0,12,13"
MaxHeight="375" />


So that's all! We will find just one more method on the cs file which I haven't talked about. It's trivial though, just changes our pointer to arrow when moving the window. I haven't also showed the styles that you will also find in the code and the fonts that I use for the sample menu. You can find the code on my google code repository.

P.S. Special thanks to my bro for all his work with styles! He is the man ;)
Windows Events going with Metro UI
This trend with Metro UI is getting quite hot nowadays and I am really interested in it. I find it extremely good looking, clear and IMHO it follows quite well with the rules of simplicity. I will save the details for another post.

At this point I was interested in some problems that a colleague (N.Baxevanis) of mine had when trying to build a Metro UI window for WPF. As you will see in his relative post he was somehow under the impression that the LocationChanged event wasn't triggered. After we solved that he was trying to  find out why another event, LostFocus, didn't fire on a Window level when he was moving his cursor to another application.
To focus or not to focus?

It seems that a lot of people have the same question around the net so I think I can clarify some things about windows in general. It seems to me that people that have no or little Windows API experience struggle when confronted with it's internals and to be honest the whole API can be a little intimidating for the newcomers.
Back to the LostFocus event... 

First of all this event does not fire on "windows forms" level. The respective events are Activated and Deactivated. On a Window level LostFocus has to do only with the windows that belong to the same application thus to the UI thread that are children of our main window. It is the expected behavior not to fire LostFocus when a user changes an application.

So one might ask: "I have seen all these cool effect that MetroTwit and Zune do when you select another applicaiton! How the $##! are they doing it?". Well, there is a nice tool called Reflector which can give you a thorough insight. But since you might not be aware of it, msdn comes to the rescue. There are two ways that can identify you application as the currently activated for the Windows operating system.


The easiest one (special thanks to my brother for this), which will be quite familiar to the high level C# developers, is to capture the LostKeyboardFocus. This event triggers always when a Window/Form/whatever looses the keyboard meaning it will fire not only when you point to another application but also when you point to another child window.

Another WPF solution (and the one I personally like more) would be to capture the Application.Activated and Application.Deactivated events or the respective window level events. I will let the msdn links tell you the rest.

The other solution that can fit our purpose is to capture the Windows events. Off course you will need to import the quite famous "user32.dll" and also have your own code for the following method:
IntPtr WindowProc(IntPtr hwnd, 
                  Int32  msg, 
                 IntPtr wParam,
                 IntPtr lParam, 
                 ref Boolean handled).

The message you are looking for is the WA_INACTIVE. This is the message sent by Windows OS to all the UI threads when one of them is getting activated/set as the foreground one.

I am sure there are a few other ways that you can make this thing work. Any proposals are always welcome!
Couch DB
Cassandra, MongoDB, CouchDB etc...
It's on my to-do list to take a deeper look onto that NoSQL trend but after seeing the following video I think I will change it's priority... (special thanks to N.Baxevanis)

CouchDB looks cool!
Posted: Τετάρτη, 15 Δεκεμβρίου 2010 3:28 μμ από gnikolaropoulos | 0 σχόλια
Δημοσίευση στην κατηγορία:
C# 5, Async Exceptions Mysteries
 

Studying the CTP of C# 5 I discovered that an asynchronous method will throw away anything other than the first exception in an AggregateException thrown by one of the tasks it's waiting for. Reading the TAP documentation, it seems this is partlyexpected behaviour and partly not. TAP claims (in a section about how "await" is achieved by the compiler):

It is possible for a Task to fault due to multiple exceptions, in which case only one of these exceptions will be propagated; however, the Task’s Exception property will return an AggregateException containing all of the errors.
Unfortunately, that appears not to be the case. Here's a test program demonstrating the difference between an async method and a somewhat-similar manually written method.

static async Task ThrowMultipleAsync()
{
   Task t1 = DelayedException(500);
   Task t2 = DelayedException(1000);
   await TaskEx.WhenAll(t1,t2);
}

static Task ThrowMultipleManually()
{
   Task t1 = DelayedException(500);
   Task t2 = DelayedException(1000);
   return TaskEx.WhenAll(t1, t2);
}

static Task DelayedException(Int32 millisecs)
{
   return TaskEx.Run(delegate
   {
      Tread.Sleep(millisecs);
      throw new Exception("Exception thrown after" + millisecs);
   });
}
The difference is that the async method is generating an extra task, instead of returning the task from TaskEx.WhenAll. It's waiting for the result of WhenAll itself (via EndAwait). The results show one exception being swallowed:
Waiting for From async method
Thrown exception: 1 error(s):
Exception thrown after 500

Task exception: 1 error(s):
Exception thrown after 500

Waiting for From manual method
Thrown exception: 2 error(s):
Exception thrown after 500
Exception thrown after 1000

Task exception: 2 error(s):
Exception thrown after 500
Exception thrown after 1000
The fact that the "manual" method still shows two exceptions means we can't blame WhenAll - it must be something to do with the async code. Given the description in the TAP documentation, I'd expect (although not desire) the thrown exception to just be a single exception, but the returned task's exception should have both in there. That's clearly not the case at the moment.
Anyone any ideas? If not then I am going back to my dungeon...
Software Design Patterns and Processes
It is strange how much an architect can understand going through the design process of a system. I have tried a few approaches and I have studied a few more, all in all I am inclined to believe that DDD gets the best out of a software developer.


I won't get into the details of DDD as the reader can get enough info around the web. It hard to get a grip of it though and I would recommend even the average developer to get some books. Thus, I strongly believe that whoever is serious about DDD should get the following:
  1. Domain Driven Design
  2. Applying Domain Driven Design and Patterns using .Net
  3. .Net Domain Driven Design with C#
Is that all though? You wish...
Truth is there are quite a few, brand new design processes. They are not widespread yet but they are gaining a lot of ground and anyone serious about designing large enterprise systems should have a serious look at them. I am going to give a bunch of links here and I will discuss each of them as we go, in new posts.

First we go with BDD or Behaviour Driven Design, an agile approach base on users and clients behaviours, trying to figure out what they want from the system. Then we have STDD (Story-Test Driven Design, which is quite interesting as we try to involve the customer to the whole process. Finally an approach not so high level is CQRS, meaning "Command and Query Responsibility Segregation". I am a bit sceptical about it yet as i think it tries to say the obvious but I won't try to present any conclusions here yet.

It is important for a developer to know why and how it chooses the design process for each project. The ability to learn a domain and quickly design a solution that fits into it separates great developers from great architects. I have met a few people with extraordinary programming skills (seriously!) who when confronted with a complex domain were intimidated. It takes time and a great amount of experience to get a grip on a domain. It is a continuous effort which, unfortunately, not many people are determined to give (especially where I live...).