DevTeach 2008

Well, I'm off to DevTeach Toronto 2008.  Track me down and say hi if you're going...

Posted by PeterRitchie | with no comments
Filed under:

RFC: Conditionals on false

Just a small request for comments.  Oren prefers

    if (GetTrueOrFalse() == false)

...instead of

    if (!GetTrueOrFalse())

Coming from 18+ years of C/C++ based language programming, I find either equally readable; but, I'm not always the one reading my code.

What are you thoughts?  Do you prefer the negation operator (!) or explicitly comparing with the false keyword?

Posted by PeterRitchie | 7 comment(s)
Filed under: ,

Fundamentals of OOD, Part 2 - Encapsulation Scope

Let's look at the ubiquitous Person concept.  It might seem logical that an application that deals with people should have a Person interface for classes to implement.  For example:

public interface IPerson
{
                String GivenName { get; set; }
                String SurName { get; set; }
                IAddress Address { get; set; }
}

At first glance this seems fine.  The IPerson interface defines attributes that the application uses with most scenarios dealing with types of IPerson, it's "well encapsulated".  But, the person concept is much more broad than what IPerson is modeling.  IPerson hasn't fully encapsulated the person concept.  A person could have parents, age, weight, height, etc.  The application doesn't need this information so it's narrowed the concept of person to fit its needs. This is an incomplete abstraction.  The type that the application needs (that is currently IPerson) should be fully abstract.  Based on the IPerson interface, a better abstraction would be ILocatableIndividual.

Let's look at the opposite of not fully encapsulating a concept. 

Let's look at another common concept, the Invoice:

public class Invoice
{
                Customer BillToCustomer { get;set; }
                Customer ShipToCustomer { get;set; }
                Datetime InvoiceDate;
                ICollection<InvoiceItem> InvoiceItems { get; }
                Single ShippingAndHandlingPrice { get; set; }
                Single CalculateSubTotal();
                Single CalculateTotal();
                Single CalculateGrandTotal();
                PurchaseOrder PurchaseOrder { get; set; }
                void Print();
}

Again, seems like a reasonable encapsulation; but it has an issue. 

There's a fundamental principle of OOD called the Single Responsibility Principle.  Robert Martin interprets the principle as "there should never be more than one reason for a class to change.".  A class should model a single abstraction.  For that abstraction to remain abstract the modeled class should have a single responsibility.  In the case of Invoice, the invoice concept should only model behaviours and attributes of an invoice.  An invoice does not print, something or someone else prints it.  With the above Invoice definition should printing need to change Invoice must also change, event though what the invoice *is* doesn't change.  Invoice is now coupled to how printing occurs.  In Martin's terms, Invoice now has two reasons for it to change: when invoice attributes change, and when how printing occurs changes. 

The Invoice class should be refactored by moving the Print method to another class.  Likely this would involve MVC, or MVP where a view would be responsible for the "printed view" and a controller or presenter would be responsible for communicating with the model (Invoice).

 

kick it on DotNetKicks.com

Fundamentals of Object-Oriented Design (OOD) Part 1

With increased usage of patterns and situationally specific strategies, people sometimes lose sight of the concepts and principles behind these patterns and strategies and fail to follow them when they're not using patterns or strategies.  I feel it's good to periodically review the fundamental concepts and first principles.

Object Oriented Design (OOD) attempts to help with the complexity of designing, writing, and maintaining software.  It attempts to allow building of software by modeling real-world objects.  As with any tool, it can be used improperly, but OOD attempts to facilitate simplicity, robustness, flexibility, etc..  OOD has many fundamental concepts.  Some of these concepts include modularity, encapsulation, and abstraction.  OOD deals with modeling behaviour and attributes of real-world objects.

Modularity is a technique of composing software from separate parts.  At the lowest level of an Object-Oriented Programming Language (OOPL), this is the definition of a type (a class or a struct in C#/C++).  Depending on the platform there may be various other levels of modularity.  In C#, for example, modularity can occur at other levels like module (source file), namespace, netmodule, assembly, etc.  Modularity is a form of encapsulation.

Encapsulation is a technique of hiding implementation details, grouping them together.  In OOPL, the lowest level of encapsulation is the type level (again, class/struct in C#/C++).  Implementation details (data) is separated from behaviour of a type.  In some OOPLs both behaviour and attributes (properties, for example in C#) are separated from behaviour.  This allows clients to decouple or to be not dependant on those implementation details. Encapsulation is a form of abstraction.

The ability to encapsulate related behaviour, attributes, and implementation allows programmers to utilize abstraction.  Abstraction facilitates separation.  OOPLs allows programmers to keep concepts separate by abstracting them from one another.  Keeping abstract concepts separate allows these concepts to evolve and be used independently.  Properly designed types allow abstraction; a File class can abstract the file system away from a particular file, for example.  The file system is part-and-parcel when dealing with files; but while dealing with a File object, it is abstracted away.

Good OOD has as little dependencies between parts as possible.  This is called lack of coupling.  One part that uses another part means the part depends on that other part.  Changes to the second affect the first.  Good OOD also has parts that contain related behaviour and attributes.  This is called cohesion.  If all the behaviour and attributes are generally used together in each scenario, the part has high cohesion.  If only some behaviour or attributes are used in each scenario, the part has low cohesion and likely should be split up.  Some people only view cohesion and coupling at the class level, I've purposely said "part" because I believe these concepts need to live throughout the modeled system, from class-level details, to modules, to namespace, to assemblies, to layers, to components, to systems, etc.

I will continue this series with the fundamental OOD principles that all good patterns should enforce.

kick it on DotNetKicks.com

Overcoming problems with MethodInfo.Invoke of methods with by-reference value type arguments

I ran into an interesting problem on the Forums recently.  Basically, when you use MethodInfo.Invoke to invoke a method with by-reference value type arguments you can't have the invoked method update a variable/argument.  The problem is, when you invoke the method the parameter is passed to the MethodInfo.Invoke via an object array.  Since we're dealing with a value type, the original value type is boxed and the invoked method actually updates the array element, not the original object (as it would with reference types).  For example:

using System;

using System.Reflection.Emit;

using System.Reflection;

using System.Diagnostics;

 

namespace InvokeTesting

{

    class Program

    {

        private const int testValue = 10;

        public static void TestMethod(ref int i)

        {

            i = testValue;

        }

        static void Main(string[] args)

        {

            MethodInfo methodInfo = typeof (Program).GetMethod("TestMethod", BindingFlags.Static | BindingFlags.Public);

            int i = 0;

            object[] parameters = new object[] {i};

            methodInfo.Invoke(null, parameters);

            // original variable isn't updated

            Debug.Assert(i == 0);

            // array element is updated:

            Debug.Assert((int)parameters[0] == testValue);

 

            // copy updated value to original variable

            i = (int)parameters[0];

 

            Debug.Assert(i == testValue);

        }

    }

}

Of course, the only "workaround" is to get the new value out of the array.

Since essentially we're implementing a run-time method invocation, a "better" way would be to create a dynamic method to make the call.  A dynamic method is a method created at run-time (whose body is generated through ILGenerator.Emit et al) and invoked via a delegate.  For example:

using System;

using System.Reflection.Emit;

using System.Reflection;

using System.Diagnostics;

 

namespace EmitTesting

{

    // delegate for void method that takes one reference parameter

    public delegate void OneRefParameterCallback<T>(ref T value);

 

    class Program

    {

        private const int testValue = 10;

        public static void TestMethod(ref int i)

        {

            i = testValue;

        }

        static void Main(string[] args)

        {

            // create a dynamic method object with arbitrary name "Caller", void return (null), and one parameter "ref int"

            DynamicMethod caller = new DynamicMethod("Caller", null, new Type[] { typeof(int).MakeByRefType() }, typeof(Program).Module);

 

            ILGenerator ilGenerator = caller.GetILGenerator();

 

            // emit ldarg.0

            ilGenerator.Emit(OpCodes.Ldarg_0);

 

            // emit call void EmitTesting.Program::TestMethod(int32&)

            MethodInfo mi = typeof(Program).GetMethod("TestMethod", BindingFlags.Static | BindingFlags.Public, null,

                                                    new Type[] { typeof(int).MakeByRefType() }, null);

            ilGenerator.Emit(OpCodes.Call, mi);

 

            // emit ret

            ilGenerator.Emit(OpCodes.Ret);

 

            OneRefParameterCallback<int> callback =

                (OneRefParameterCallback<int>)caller.CreateDelegate(typeof(OneRefParameterCallback<int>));

 

            // call our emitted code with a reference parameter

            int i = 0;

            callback(ref i);

            Debug.Assert(i == testValue);

        }

    }

}

In this example, the method invocation directly updates a value type variable.  This could be made more re-usable to refactoring the dynamic method creation code into it's own method.

kick it on DotNetKicks.com

Resharper Isn't Always Smart

I was writing some code today, essentially like this:

public class MyClass

{

    private int value;

    public MyClass(int value)

    {

        this.value = value;

    }

    public static bool operator==(MyClass left, MyClass right)

    {

        return left.value == right.value;

    }

 

    public static bool operator !=(MyClass left, MyClass right)

    {

        return !(left == right);

    }

}

    //...

    MyClass myClass1 = new MyClass(1);

    MyClass myClass2 = new MyClass(1);

    if((Object)myClass1 != (Object)myClass2) // "Type cast is reundant"

    {

        Console.WriteLine("not equal");

    }

    else

    {

        Console.WriteLine("equal");

    }

...where Resharper warned that both the casts to Object were redundant and offered a "Quick-fix" (red light bulb) to "Remove cast".  Well, doing that to one of the casts results in a compile error so you have to manually change the other; but what it's suggesting is this:

    if(myClass1 != myClass2)

This completely changes the output of my application from "not equal" to "equal".  What Resharper doesn't know (or doesn't care to check) is that removing those casts switches from a reference comparison to a value comparison and may have different results.  What I wrote with the original code was to test if the two references referenced the same object.  The default behaviour of a class is to do a reference check; but I've overloaded operator== (and operator !=) to perform a value comparison (I've left out the lovely bits that truly gives MyClass value semantics for clarity).

So, when Resharper offers to change your code, be sure you know side-effects of that change before you let it do it.  You could introduce a nasty bug.

kick it on DotNetKicks.com

Posted by PeterRitchie | 11 comment(s)
Filed under: , ,

Licences for Microsoft products

Occasionally I get development questions that are governed by one or more product licenses (End-User License Agreement, "EULA").  One question that I see is "I've used Reflector to decompile the .NET Framework and want to use that C# code in my application".

You've installed some Microsoft software and agreed to the EULA but didn't save it and it's nowhere on your hard-disk.  If you're not sure what your license terms are, there's a Microsoft web page that allows you to look up EULAs for many products: http://www.microsoft.com/about/legal/useterms/

 By the way, the answer to the question is "You're not licensed to do that".  Anyone know what clause in which EULA denies that?

kick it on DotNetKicks.com

Posted by PeterRitchie | 7 comment(s)
Filed under: ,

Upcoming C# 3 Guidance From Microsoft

Mircea Trofin has some design guidelines with regard to some C# 3 language additions (that I assume will make it into a revised Framework Design Guidelines of some sort).  They more less agree with the guidelines I published in Code Magazine a while ago.  There are some slight differences:

Consider using extension methods in any of the following scenarios: to provide helper functionally relevant to every implementation of an interface... and,

Do define extension methods in the same namespace as the extended type, if the type is an interface, and if the extension methods are meant to be used in most or all cases.  This applies to framework designers that are publishing interfaces but also want to publish callable methods that apply to all implementation of those interfaces.  My article approaches the guidelines more from a non-framework designer.  I do agree that extension methods to extend interfaces is very useful and is probably one of the most adept use of extension methods.  Although, I think the wording of this guideline could use improvement.

Avoid defining extension methods on System.Object, unless absolutely necessary.  Good advice.

Do not define extension methods pertaining to a feature in namespaces normally associated with other features.  Instead define them in the namespace associated with the feature they belong to, or a namespace of it.  This is really unclear (and seems to suggest contradicting the first guideline: Avoid frivolous use of the extension methods feature when defining methods on a new type.  Use the canonical, language-specific means for defining type members).  I'm assuming the jist of this is, as a framework designer, don't arbitrarily put extension methods in the namespace of the type the method applies to, consider putting the extension method in a more applicable namespace, if possible.  For example, if you want to declare an extension method "Forward" for Telecom.INode implementations, putting the method in a "Routing" namespace would be better than arbitrarily putting it in the "Telecom" namespace.  I've changed the Mircea's guidance slightly to use a interface in the example--which I think makes it more clear.

Mircea also includes Consider using extension methods in any of the following scenarios:... when object model considerations would dictate taking a dependency on some assuming but taking such a dependency would break dependency management rules.  This means, should you need to add a method to a class but adding that method would create cyclic dependency or would cause a lower level assembly/class to be dependant on a higher level class, break the method out into another assembly as an extension method.  Use this advice with caution; I would argue that if you think you need a method like this at all (even if implemented as an extension method), you likely have some design problems and should only be considered when revising a published framework, and not when creating a new framework.

Another tidbit of guidance that came about after I wrote the article and Mircea doesn't mention is that extension methods can make writing fluent interfaces much cleaner by separating the state management concern of supporting a fluent interface from the class that it applies to.

Thoughts?  Any additional guidance you feel has been overlooked (with regard to extension methods and LINQ)?

kick it on DotNetKicks.com

Single-Entry, Single-Exit, Should It Still Be Applicable In Object-oriented Languages?

Before the modern high-level languages Edsger Dijkstra came up with "Structured Programming".  This programming methodology relied on the programmer to form and enforce most of the structure of the program--manually keeping sub-structures and logic separate from one another to promote maintainability and easy of understanding, among other things.  Think assembly language with a linear collection of instructions and jumps and then the only concept of a method or function is how the rest of the logic jumps to that block of code.

This concept of delineating functions hinged on a single entry, i.e. from point A to point B only one point is actually jumped to from "external" code.  This single entry concept usually included a single exit, to ease the delineation of a "function".  This is known as the single-entry, single-exit methodology (SESE).

It's hard to think of multiple entry points with modern high-level languages what with object-orientation and abstraction and encapsulation; but it's easy to see multiple exits from a method.  For example:

        public static int CountCommas(string text)

        {

            if (String.IsNullOrEmpty(text))

            {

                return 0;

            }

            if (text.Length == 0)

            {

                return 0;

            }

 

            int index = 0;

            int result = 0;

            while (index > 0)

            {

                index = text.IndexOf(',', index);

                if (index > 0)

                {

                    result++;

                }

            }

            return result;

        }

Structured programming (at least SESE) suggests writing the method like this instead:

        public static int CountCommas(string text)

        {

            int result = 0;

            if (!String.IsNullOrEmpty(text))

            {

                if (text.Length > 0)

                {

                    int index = 0;

                    while (index > 0)

                    {

                        index = text.IndexOf(',', index);

                        if (index > 0)

                        {

                            result++;

                        }

                    }

                }

            }

 

            return result;

        }


This concept may have made for more readable code when Dijkstra first cemented the concept in the late 60's early 70's; but in Object-Oriented languages I believe it's less readable.  For one thing, it's difficult to shoe-horn SESE with other language concepts like exceptions:

        public static int CountCommas(string text)

        {

            Exception exception = null;

            int result = 0;

            if (!String.IsNullOrEmpty(text))

            {

                if (text.Length > 0)

                {

                    int index = 0;

                    while (index > 0)

                    {

                        index = text.IndexOf(',', index);

                        if (index > 0)

                        {

                            result++;

                        }

                    }

                }

                else

                {

                    exception = new ArgumentException("argument of zero length", "text");

                }

            }

            else

            {

                exception = new ArgumentNullException("text");

            }

 

            if (exception != null)

            {

                throw exception;

            }

 

            return result;

        }


And this technically still violates SESE since we exit via return or via throw, although they have close proximity.

I believe the above example is hard to read and hard to maintain.  I would abandon the SESE trappings of structured programming in favour of:

 

        public static int CountCommas(string text)

        {

            if (String.IsNullOrEmpty(text))

            {

                throw new ArgumentNullException("text");

            }

            if (text.Length == 0)

            {

                throw new ArgumentException("argument of zero length", "text");

            }

 

            int index = 0;

            int result = 0;

            while (index > 0)

            {

                index = text.IndexOf(',', index);

                if (index > 0)

                {

                    result++;

                }

            }

            return result;

        }

In high-level languages that do have concepts like functions, subroutines, or methods, the "Single Entry" aspect of SESE is moot, evolving to the concept of "Single Exit" or the "Single Point of Exit From Methods Principle".  This seems like a Cargo Cult to me--separating the part of a concept that is no longer obviously archaic in the hopes of getting the same result in a different context.

Interestingly, as I was writing this, Patrick Smacchia posted to his blog about NDepend and Nesting Depth--which basically details metrics that show the SESE implementations I show above would actually have higher nesting depths than the non-SESE implementations and thus be more complex, less readable, and less testable.

 What are your thoughts?  Do you generally follow Single Point of Exit From Methods Principle?  If you do, do you ignore it for exceptions?

kick it on DotNetKicks.com

No "Add Method Stub" When Passing or Assigning Delegates

I finally noticed the other day the "Add method stub" SmartTag wasn't appearing for a new method name I type in.  I decided I'd have a closer look...

When you're practicing Test-Driven Development (TDD) you want to write a test for methods before you write the methods.  This means you write a test method that calls several other methods that don't exist yet.  The Visual Studio IDE, in an effort to promote TDD, recognizes this and when you have your caret over a call to one of these methods a SmartTag shows up and you can select Generate method stub for 'SomeMethod' in 'SomeNamespace.SomeClass'.  For example, if you have the following:

    static void Main(string[] args)

    {

        SomeMethod();

    }

...if you place the caret (e.g. click on "SomeMethod") somewhere on "SomeMethod" (and it doesn't exist in the current class) the SmartTag rectangle under the 'S' in SometMethod appears and you can hover your mouse over the word "SomeMethod" and the options icon appears that you can click and select Generate method stub for 'SomeMethod' in 'SomeNamespace.SomeClass', and it will generate a method like the following:

    private static void SomeMethod()

    {

        throw new NotImplementedException();

    }

Well, I figured this would also happen when I tried to assign a non-existent method to a delegate.  For example, if I had the following:

    static void Main(string[] args)

    {

        Action action = SomeOtherMethod;

    }

...I would expect that placing the caret over "SomeOtherMethod" that the SmartTag would show up and I would be able to select 'SomeOtherMethod' in 'SomeNamespace.SomeClass' and it would generate a method like the following:

    private static void SomeOtherMethod()

    {

        throw new NotImplementedException();

    }

Alas, the IDE doesn't recognize use of an undeclared method when used with delegates.  i.e. it doesn't appear in these circumstances either:

    static void ProcessDelegate(Action action)

    {

        //...

    }

    static void Main(string[] args)

    {

        ProcessDelegate(SomeOtherMethod);

        ProcessDelegate(new Action(SomeOtherMethod));

    }

I thought "Add method stub" would be more useful in these circumstances because you're not explicitly passing arguments to the method so it's more likely that you don't know what signature you need to declare.  So, I logged a suggestion for it: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=328782

By the way, the non-generic Action delegate (System.Core.Delegate) is new to .NET 3.5.

My Wishlist for C# 4

[Edit: fixed the not-ready-for-publication problems] 

There seems to be more than few people blogging about what they hope C# 4 will do for them.  I haven't seen one that really synchronizes with my thoughts, so I'd thought I'd post my own list.

Variance

A good story with regard to variance with generics is vital for upcoming versions of C# 4.  You could argue that this should have been done in 3, but, unfortunately, that wasn't the focus.  I think this really needs to be done for 4; and if Eric Lippert's blog is any indication, that may come true.

Design By Contract 

Design by Contract (DbC) means programmers can define verifiable interfaces.  This explicit intention information is then used by the compiler to greatly increase the compile-time checking it can do.  In most cases this means no checking need be done at run-time because the compiler has verified the that condition cannot occur at run-time, increasing reliability and improving performance.  There's hint of this in the framework already with the internal classes ImmutableAttribute and InvariantMethodAttribute.  First-class language support for DbC would go a long way to being able to write more reliable software.

Concurrency

Various leaders in the industry (Microsoft included) are recognizing the processor speed improvements will essentially stop being vertical and continue to be horizontal (i.e. instead of increases in processor speed, increases in processors or cores will be the norm).  This means that in order for applications to utilize that type of system processing throughput concurrency will become more mainstream.  Microsoft has various concurrency initiatives going on (like the Parallel Framework Extensions).  It's only logical that lessons learned from this project not long will make their way into the BCL and the .NET Framework but also into the respective languages (C# included, I hope).  In this respect I hope that concurrency issues become first-class citizens in the library.  This would include things like immutability.  In the spirit of Agile development, the sooner this gets into the language the sooner it can be embraced and evolve.

Object-Oriented Programming

Much like Jon Skeet, I believe the language designers should recognize that C# is an object-oriented language first and foremost.  This fact should continue to focus what, if any, aspects of other programming paradigms are added to the language. Paradigms like Aspect-Oriented Programming, Functional Programming, etc.

infoof, memberof, propertyof, eventof, methodof Operators

The information these operators require is so easy for the compiler to simply dump in the IL stream.  For users to do the same thing requires that they have a string containing the name of the member in question--which can't be checked at compile time and leads to maintenance nightmares.  Imagine what life would be like without the typeof operator forcing use to use code like this:

    Type type = Type.GetType("MyNamespace.MyClass");

Instead of:

    Type type = typeof(MyNamespace.MyClass);

...if I rename MyClass to UsefulClass no refactorying tool I've see will modify the "MyNamespace.MyClass" string and compilation will succeed and lead to a runtime-error.

Cleanup Some Long-standing Issues.

The above and variance could be viewed as a long-standing issues; but, I think they deserves to be called-out on they're own, they would be huge improvements.  Detection of recursive properties, for example.  The C# team have a backlog of a few things like this; now's the time.

Extensible Compiler

Years back my original idea for this was to have an IDE that automatically corrects mistakes.  e.g. if an "; expected" error was spit out, the IDE could intercept it, correct the code, and recompile.  But, this extensibility idea can be so much more than that.  This sort of extensibility could introduce Aspect-Oriented Programming fundamentals or Domain-Specific Language abilities without the language really understanding the concepts at all.  This extensibility would be very powerful for programmers and would give them the ability to evolve their language without being tied to the release schedule of the C# team.

Thinking Out Loud

Class-scoped aliases: Aliases in C# are a bit of a pariah, they're at global, file scope; making them not all that useful.  In C++, for example, it's quite common to declare type aliases within a class declaration (usually based on a templated type).  It would be nice to be able to create an instance of a type based on an alias within a class.  E.g. MyType.MyAlias o = new MyType.MyAlias;

 

kick it on DotNetKicks.com
Posted by PeterRitchie | 4 comment(s)
Filed under: , ,

Playing with LINQ

If you're interested in seeing what you can do with LINQ and want to learn the syntax, there's a wonderful new utility called LINQPad that is available.  It basically lets you type in LINQ statements (or create statements from tables) and see what the result would be with a given database.

Posted by PeterRitchie | with no comments
Filed under: ,
More Posts Next page »