Posts tagged with c - page 14

Do not expose the implementation

One of the things we are taught in object oriented design is that the outside world should not be exposed to the complexities of how our object achieves their goals. Other developers are busy, don’t care and really don’t need to know. It is a sound idea and goes hand-in-hand with ease of use.

Televisions used to expose the implementation with a single tuning knob that had to be adjusted every time you wanted to watch another broadcast. With time engineers replaced this with an interface that hid the implementation, specifically the concept of channels where each one could be individually tuned and switched between on a whim. Implementation no longer exposed.

Technology brings complexity but only good technology makes it look simple.

One thing that has always annoyed me here in the UK is an every day object that doesn’t hide the implementation.

Taps.

That’s right taps. I don’t care that water is delivered to my sink through two pipes, hot and cold. I don’t ever want scolding hot water and just as rarely require it uncomfortably cold. Most of the time I want the same warm temperature as last time.

Sure, there are taps that do this and indeed in many other countries it seems to be the norm but here in the UK builders keep putting in separate hot and cold taps in. Until either the public wise up or I actually buy my own house and can replace this sort of annoyance I’m stuck with it.

While taps have annoyed me for a while it was .NET 2.0 that reminded me of the whole issue again and a brief discussion with GrinGod that caused a similarly titled post of his own. Specifically the Hashtable class is now called Dictionary when used with generics which once again prevents the implementation details leaking out into your code. Important in this case because most people wanted a fast dictionary and didn’t care too much how it was achieved and also because that algorithm changed in .NET 2.0 and they realized they shouldn’t have specified the implementation in the class name…

If you previously generated strongly-typed collections in .NET 1.1 using the many tools around such as CodeSmith then you might be interested in this little tip. If you have a strongly typed class such as:

public class MyObjectCollection : Hashtable {
  public MyObject this[object key] {
    get { return (MyObject) pHashtable[key]; }
    set { pHashtable[key] = value; }
  }
}

Then instead of replacing every single instance of

var theseObjects = new MyObjectCollection();

with

var theseObjects = new Dictionary<object, MyObject>;

you can in fact simple change MyObjectCollection and leave the rest of your code alone:

public class MyObjectCollection : Dictionary<object, MyObject> { }

Which will also mean that you can still have the additional properties and functions on MyObjectCollection if you had them previously. It’s rather obvious you can do this but many samples I’ve seen just create raw generic collections everywhere rather than inheriting from them.

[)amien

NullableTypes 1.3.1 beta

In my early .NET days I ran into a problem many developers integrating with other systems do. Unlike XML with it’s xsl:nil or database fields with <null> the standard .NET value-types don’t support the concept of null for missing values. It’s such an important omission that Microsoft implemented it in .NET 2.0 (now gone RTM and up on MSDN) with a generics class named [Nullable](http://msdn2.microsoft.com/en-us/library/1t3y8s4s%28en-us,vs.80%29.aspx) and a little syntactic sugar to help it go down smoothly.

For those of us still working with .NET 1.1 the NullableTypes project provides null-capable versions of all your favorite .NET types and unlike the SqlTypes included in .NET these match the System types for precision and provide support for .NET remoting and web services.

Yesterday NullableTypes 1.3.1 beta was release which adds (since the last 1.2 stable release):

  • New types (NullableGuid and NullableTimeSpan)
  • DateTime.Add method returns new instance in keeping with the the other immutable classes
  • Security enhancement (reduced needed permissions/attack surface)
  • NullableInt16.GetHashCode now returns hash codes identical to Int16
  • Improvements and additions to the unit tests

With my contributions now including NullableGuid, NullableTimeSpan and implementing IXmlSerializable I am finally feeling like an open source/free software contributor.

I’ve got a few more ideas for NullableTypes that I’ll be working through with LuKa around unit testing and .NET 2.0 source compatibility.

[)amien

Automatic comparison operator overloading in C#

Abhinaba has blogged on the painful C# operator overloading experience.

The basic problem that is if you want to overload one, you soon end up many of the tests including == != < <= > >= Equals, Compare and probably CompareTo via IComparable when it turns out one function can provide everything needed in general use.

GitHub has the latest version of AutoOperators

Ruby already has this with the <=> operator, sometimes known as a SpaceShipOperator and this got me thinking resulting in the following little class:

using System;

/// AutoOperators provides a base class where all the standard operators are overridden and
/// wired up via the subclass's implementation of IComparable.CompareTo.
public abstract class AutoOperators : IComparable {
  public static bool operator < (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) < 0;
  }
  public static bool operator > (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) > 0;
  }
  public static bool operator == (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) == 0;
  }
  public static bool operator != (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) != 0;
  }
  public static bool operator <= (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) <= 0;
  }
  public static bool operator >= (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) >= 0;
  }

  public static int Compare(AutoOperators obj1, AutoOperators obj2) {
    if (Object.ReferenceEquals(obj1, obj2)) return 0;
    if ((object)obj1 == null) return -1;
    if ((object)obj2 == null) return 1;
    return obj1.CompareTo(obj2);
  }

  public abstract int CompareTo(object obj);
  public abstract override int GetHashCode();

  public override bool Equals(object obj) {
    if (!(obj is AutoOperators)) return false;
    return this == (AutoOperators) obj;
  }
}

And then to use it simply inherit from it and implement GetHashCode and CompareTo, e.g.

using System;

public class SampleClass : AutoOperators {
  private int testValue = 0;

  public SampleClass(int initialTestValue) {
    testValue = initialTestValue;
  }

  public int TestValue {
    get { return testValue; }
    set { testValue = value; }
  }

  public override int CompareTo(object obj) {
    if (obj is SampleClass)
       return TestValue.CompareTo(((SampleClass) obj).TestValue);
    else
       return -1;
  }

  public override int GetHashCode() {
    return TestValue.GetHashCode();
  }
}

As with all code, determine the suitability of this solution to your own needs – that responsibility is yours. As with all code here it comes without warranty, expressed, implied or otherwise alluded to.

I’d recommend checking out the performance, CLS compliance regarding operators and the addition of any extra operators you use all the time.

[)amien

Conditional operator bug in .NET 1.x & 2.0

I encountered a strange problem this week when a conditional operator appeared to be evaluating the false expression contrary to the C# documentation. The line looked like:

return (testObject == null ? null) : testObject.InstanceVariable;

The point of this line is to prevent accessing .InstanceVariable if the object is null and yet every time this line executed a NullReferenceException is thrown (and no I wasn’t overloading the == operator).

With a little experimentation I was able to narrow it down and produce a simple test case that exercised the bug on .NET 1.1 and .NET 2.0.

The problem is this: If the return parts are not of the same type and one of the members supports implicit conversion to the expect type, then it is called regardless of whether it is the the true part or not.

I filed the bug with Microsoft and it was confirmed last night by one of their C# engineers, there is a small chance it will be fixed in .NET 2.0 before release but we’ll have to see. I checked out some of the .NET classes and they too always access the object during an implicit conversion, however they are all value types which can not be null.

In the mean time there is an easy way to avoid this by modifying your implicit conversion methods to check for null before converting.

public static implicit operator string(ClassWithImplicitConversion objToConvert) {
    return objToConvert == null ? string.Empty : objToConvert.ToString();
}

A full test case appears below:

using System;

namespace ProveConditionalBug {
     class Program {
         static void Main(string[] args) {
             Console.Out.WriteLine("Testing... " + ProveConditional());
         }

        static string ProveConditional() {
            ClassHoldingImplicitConversionMember testObject = null;
            return (testObject == null) ? null : testObject.InstanceVariable;
        }
     }

    class ClassHoldingImplicitConversionMember {
        public ClassWithImplicitConversion InstanceVariable = null;<br />     }

    class ClassWithImplicitConversion {
         public string Value = "Test";
         public static implicit operator string(ClassWithImplicitConversion objToConvert) {
             return objToConvert.Value;
         }
     }
}

[)amien