Bookmark and Share

Int32 + String = String

by KodefuGuru 16. August 2010 19:18

This past weekend, we were throwing around C# trivia at a bar in Baton Rouge after SQL Saturday #28. Another speaker asked me one that he used in his session that day: what happens if you call Console.WriteLine(5 + “5”). I nonchalantly replied, “the number 55 written to the console.”

It really never occurred to me to attempt to add an int to a string, so I encountered this behavior in the context of something a little more bizarre: creating LINQ to Object. Here’s the extension method I used.

public static TResult SelectMany<TSource, TCollection, TResult>(this TSource source, 
    Func<TSource, TCollection> collectionSelector, 
Func<TSource, TCollection, TResult> resultSelector) { return resultSelector(source, collectionSelector(source)); }

There’s nothing particularly special about this extension method, but it allows you to combine two objects in a query expression. My first test was with types of the same kind.

[TestMethod]
public void SelectMany()
{
    var result = from x in 2
                 from y in 3
                 select x + y;

    Assert.AreEqual(5, result);
}

I know, that’s a really long-hand way to write 2 + 3. However, it proved that the SelectMany extension method worked. I then attempted it with an integer and a double. By all the rules, it should return a double.

[TestMethod]
public void SelectManyDifferentTypes()
{
    var result = from x in 2
                 from y in 3.1
                 select x + y;

    Assert.AreEqual(5.1, result);
}

Again, this was worked as I thought it would. But as I played with modifying the test to do an integer and a string, I noticed that it still compiled without any modifications to the select clause. Here’s the final test.

[TestMethod]
public void SelectManyIntAndString()
{
    var result = from x in 4
                 from y in "2"
                 select x + y;

    Assert.AreEqual("42", result);
}

I was dumbfounded. Was the act of passing the types through functions working magic with the types? I had to test it out on straight code to find out.

[TestMethod]
public void IntAndString()
{
    var result = 4 + "2";

    Assert.AreEqual("42", result);
}

There is no magic, unless you believe the compiler is a mystical force that binds all your code together. This is one of the compiler rules I had not encountered simply because it never occurred to me to add an int and a string together. I was expecting a type mismatch, but I missed one simple rule about strings buried deep in the C# specifications.

Whenever you use the + operator with a string, a string concatenation is performed. With a type that isn’t a string, this ends up calling String.Concat(object, object), which will use the ToString method of the object. If the parameter is null, String.Empty is used. You know all those places where you see “Hello “ + World.ToString() + “!!!”; completely unnecessary call to ToString().

Just because you know this works doesn’t mean you should do it. Readability of code is more important that doing tricks with strings. I would recommend calling ToString() when concatenating, prefering String.Format over concatenation, and using StringBuilder with large amounts of strings. But hey, it makes a great trivia question.

Tags:

Kodefu

Bookmark and Share

Is That Closure or Inheritance?

by KodefuGuru 10. August 2010 19:09

In response to my previous story, a commenter asked if the code I posted works due to a closure relationship rather than inheritance. The argument is that the field can be accessed by a nested class, and it wasn’t actually passed as a member to the other class. The reader of the story states that the field would still be accessed in Java even if Employee didn’t inherit from Person. Then, the question is asked if it’s different in C#.

I’m not familiar enough with Java to speak about how it works, but I can discuss what is happening in C#. First, let’s take a look at the code in question.

public class Person
{
    private string message;

    public override string ToString()
    {
        return message;
    }

    public static Person CreateEmployee()
    {
        return new Employee();
    }

    class Employee : Person
    {
        public Employee()
        {
            this.message = "I inherit private members!";
        }
    }
}

The reason you can be sure the constructor of Employee modifies the member named message on the instance of employee is because of the ‘this’ keyword. This keyword refers to the current instance, and this is the reason I don’t bother with underscores or funky names in my fields. If I need to scope to a member field, using the ‘this’ keyword is clearer than semantic customs… plus it has compiler support! Using ‘this’ within a nested type only refers to members of that type, and not the outer type

Of course, I use the keyword for convention, it oftentimes isn’t necessary. What happens If I remove the ‘this.’ from ‘this.message’?

public Employee()
{
    message = "I inherit private members!";
}

It still compiles, but whereas the answer was clearly “it’s inheritance” before, the lack of the keyword brings lack of clarity. So what’s happening? We could bring it up in reflector, but it would be more fun to modify the code. Let’s actually strip the inheritance hierarchy. This will require a few other modifications.

public class Person
{
    private string message;

    public override string ToString()
    {
        return message;
    }

    public static Employee CreateEmployee()
    {
        return new Employee();
    }

    public class Employee
    {
        public Employee()
        {
            message = "I inherit private members!";
        }
    }
}

And we find out quickly enough that this is will not work. Despite the lack of ‘this’, message was referring to the private member on Employee. Since Employee no longer inherits from Person, it is trying to access the field in the outer class. This gives us a rare error message.

Cannot access a non-static member of outer type 'Person' via nested type 'Person.Employee'

There’s a very simple explanation for this. Employee has been nested inside of Person. Just because you have an instance of the nested type does not mean you will have an instance of the outer type. Nesting allows for interesting accessibility scenarios, but there is no other special relationship defined.

The accessibility relationship works like this. I can create a method inside of Employee to access a private member of Person.

public class Employee
{
    public void Demo()
    {
        var person = new Person();
        person.message = "accessed";
    }
}

In the original version, it is possible to access the message field of Person from Employee if the message field is static as no instance is required.

I am not sure how this all works in Java, but my original example demonstrated inheritance with private accessibility. Try it out for yourself!

Bookmark and Share

Are Private Members Inherited?

by KodefuGuru 9. August 2010 17:30

When I interview someone, I start the question phase with simple object-oriented questions to get a feel for the person. Am I interviewing someone who writes rote procedural code or do I have someone in front of me who thinks in terms of objects and relationships. Even more intriguing, am I talking to a functional wunderkind who will enlighten me in my own journey through code? I start off with the simplest of questions: what’s the difference between a class and an object? Of course, the topics usually end up deep into their own experience as I use technical questions for the response factor more than right or wrong answers. I’m more interested in the fact that someone is thoughtful, into programming, and able to learn rather than whether they memorized a textbook or interview prep site.

A person came to me today to ask me a question they had recently in an interview for a C# position: are private members inherited? The answer given was no, and the interviewee was promptly informed that answer was incorrect.

On one level, it would appear that classes don’t inherit private members. Public and protected members are accessible by the subclass, but those pesky privates seemingly can’t be accessed. Of course, they’re there, otherwise calls to the exposed methods would not work. Then, there’s always reflection to access them. But I’m not really concerned about reflection or lower-level activities such as memory access; I’m more interested in the higher level concept of inheritance. Is the private member passed on to the subclass?

The problem with the private member isn’t actually one of inheritance, it’s one of accessibility. Being a private member means it’s only accessible within its defining type. To discover if the private members are inherited, we can set up a simple test: define the subclass within its parent.

public class Person
{
    private string message;

    public override string ToString()
    {
        return message;
    }

    public static Person CreateEmployee()
    {
        return new Employee();
    }

    class Employee : Person
    {
        public Employee()
        {
            this.message = "I inherit private members!";
        }
    }
}

Run this within a Console application, and it will print the message on the screen: “I inherit private members!”

class Program
{
    static void Main()
    {
        Console.WriteLine(Person.CreateEmployee());
    }
}

Proof positive that private members are actually inherited. Remember, modifiers such as public, protected, private, and internal are all accessibility modifiers. These modifiers affect encapsulation rather than inheritance.

A class takes everything from its parent class; its instantiation will have every member. In most situations, those marked private are hidden from from the subclass. Using reflection follows this same behavior: with the example above, message will not be returned through type.GetMembers(BindingFlags.NonPublic|BindingFlags.Instance) despite the fact that it has been exposed.

I do, however, feel that the concept of encapsulation and inheritance coexist and are intertwined. Certainly, at a physical level, the instance of the object has the same memory, and therefore can access the functionality that has been hidden from it through the interface its parent has given it. But conceptually, one does not look at a class and consider members that have been hidden from view as being part of it. Instead, we think of a class as inheriting an interface and behavior, not the entire template. I may inherit my parents’ features, but their secrets are theirs to keep.

I did demonstrate a way to break the way many think about inheritance in C#. Some languages don’t allow access beyond the public interface even to their subclasses. In those languages, inheritance doesn’t break encapsulation, and I believe the case is stronger that encapsulation makes our conceptual view more valid. Don’t get me wrong though, the accessibility modifiers in C# are very useful, and I wouldn’t trade them for a more “pure” language.

If I were the one asking the interview question, I would not be interested if the candidate got the question right with a simple yes or no answer. I would ask why in either case. Most people probably would respond that “objects can’t access private members of the parent class,” despite the fact that I’ve proven it can be done. Does that make the person a bad developer? No, because that is true in nearly all situations, and it describes, without being too technical, encapsulation. That would be a good time for me to follow up with encapsulation. What if instead the person knew how to access the parent’s private members through inheritance, then proceeded to provide more information about encapsulation and inheritance? Well, kudos, maybe you read my blog? In all seriousness though, if someone came back to me with that information I would be impressed simply because they care enough about their craft to learn it, just as I am impressed when someone cares enough to discuss these topics at conferences because they are truly interested in learning.

Bookmark and Share

Summation Functions

by KodefuGuru 26. July 2010 17:31

Creating a summation function in C# isn’t difficult in itself. After all, it is perfectly reasonable to create functions that consist of more than one line. What is interesting is abstracting it so that any function can become a summation function.

Here is the Madhava-Leibniz function for pi:

Madhava-Leibniz Formula for Pi

Here’s how we can define the inner function:

Func<Int32, Double> f = k =>  4 * (Math.Pow(-1, k) / ((2.0 * k) + 1));

What we want to be able to do is call f.Sum(). This will generate a summation function that calculates pi. Here’s how we accomplish that task.

public static Func<Int32, Double> Sum(this Func<Int32, Double> func, int start = 0)
{
    return end =>
    {
        Double result = default(Double);

        for (int k = start; k <= end; k++)
        {
            result += func(k);
        }

        return result;
    };
}

We need to accumulate the results of every pass into the function. The resulting summation function will still require a parameter representing the upper bound. This is because we actually do need to return at some point in time to inspect the result.

Here’s the test to prove this works.

[TestMethod]
public void Pi()
{
    Func<Int32, Double> f = k =>  4 * (Math.Pow(-1, k) / ((2.0 * k) + 1));
    var calculatePi = f.Sum();
    Assert.AreEqual(3.14159, calculatePi(200000), 7);
}

With 200,000 passes, we can ensure an accuracy of 7. Leibniz didn’t rediscover the most efficient way of calculating pi, but it works for a test of the Sum extension method.

If we switch context to VB, we can even use this with a query expression! A couple of things. 1) VB 10 has a bug and can’t handle the optional parameter… change it to a traditional overload and 2) we need a Cast method.

I’ll let you figure out how to make a traditional overload. The cast method won’t actually do anything (because it will break the function), but we need it because the query expression will try to use it.

public static Func<T, TResult> Cast<TCast, T, TResult>(this Func<T, TResult> func)
{
    return func;
}

Here’s the VB test that uses LINQ!

<TestMethod()>
Public Sub Pi()
    Dim f As Func(Of Integer, Double) = Function(k) 4 * (Math.Pow(-1, k) / ((2.0 * k) + 1))
    Dim calculatePi = Aggregate x In f Into Sum()
    Assert.AreEqual(3.14159, calculatePi(200000), 7)
End Sub

I think it’s easier to just call f.Sum(), but this should give you a taste of where I will be taking things with future articles.

Download the source code from CodePlex!

Bookmark and Share

Monadic Comprehensions Presentation at IEEE ICCSIT 2010

by KodefuGuru 10. July 2010 02:43

Here is the slide deck from my talk at IEEE ICCSIT 2010. The preparation for this conference and my research into monadic comprehensions and functional composition happened to coincide, so I decided I should make that my presentation. China has been an adventure, enjoy the code I created to go along with it!

Synopsis: Build monads using the C# language with a C# style, then use the appropriate methods to ensure the LINQ query syntax works with this functional design pattern. After describing monads, cut the middle man and apply the same techniques directly to objects and functions to achieve better results with a declarative syntax.

Source code from demo is available at monadic.codeplex.com.

Bookmark and Share

TryParse vs Convert

by KodefuGuru 24. June 2010 01:41

Since I’ve been coming out against out params, I sometimes get asked about the TryParse pattern. My typical response is that the most egregious offenses of out param usage occur when there is more than one, but even one should be avoided. However, I was recently presented with a more specific question: “lets say you had to pick up a query string param in WebForms/ASP.NET and make it an Int32... would use Convert or TryParse?” This is a very practical question, and given the choices it is interesting to examine for the best practice.

TryParse

int index;
int.TryParse(Request.QueryString["index"], out index);

This version isn’t so bad since it requires no conditional processing. The problem with the TryParse method is the out parameter, which requires the initial declaration of variable whether or not you want or need it. This also prevents it from being used in a declarative statement, since the return value is whether the value was parsed. This can be used declaratively using the ternary operator, but it is rather odd since the result is already defined. Many people opt to use imperative logic instead, testing for !<t>.TryParse.

Here’s are examples of non-zero default value. The first using an if statement and the second with the ternary operator.

int index;
if (!int.TryParse(Request.QueryString["index"], out index))
{
    index = 1;
}
int index;
index = int.TryParse(Request.QueryString["index"], outindex) ? index : 1;

Convert

var index = Convert.ToInt32(Request.QueryString["index"]);

Convert is more declarative in this form, but it has a fatal flaw. If the string being parsed is an invalid value (not null, but something like “asdf”), then it will throw an exception. Exceptions are expensive, and it requires wrapping the code in a try… catch block since the exception is typically meaningless aside from preventing the assignment. Perhaps the above statement would be better expressed as:

int index = 0;
try
{
    index = Convert.ToInt32(Request.QueryString["index"]);
}
catch { }

Yuck.

Maybe

In the response to the question on which method of parsing the query string param I would use, I rejected both typical solutions. They both have flaws I find distasteful. Why not parse the string and return a Nullable<T> so the caller can decide what to do with it?

int index = Maybe.ToInt32(Request.QueryString["index"]) ?? 0;

Simple and declarative. Maybe’s methods wrap the TryParse methods since they appear to be more efficient than Convert’s methods. The idea is that complexity should be hidden, and code should be made more declarative. I believe the Maybe class achieves it. The name was chosen because a non-generic Nullable class already exists, and Maybe seemed a sound choice since it may be a value or it may be nothing.

Conversion Failures

The typical conversion failure use case is to assign a default value. However, additional logic is sometimes necessary. With TryParse, you test the return value for false. With Convert, you catch the exception. With Maybe, you test for null.

int? result = Maybe.ToInt32(Request.QueryString["index"]);
if (result == null)
{
    // Failure processing
}

Since it is sometimes necessary to know if a the parsing was successful, I didn’t opt to create a ParseWithDefault method.

Download the source code from kodefu.codeplex.com.

Bookmark and Share

Down the Functional Rabbit Hole

by KodefuGuru 11. June 2010 16:51

In the comments to “Get Rid of out Parameters,” a reader mentioned a technique that I neglected to cover: the functional continuation-passing style. Here’s how Ram presented it.

static void Main()
{
    Div(16, 3, (quotient, reminder) =>
    {
        Console.WriteLine("quotient: {0}", quotient);
        Console.WriteLine("remainder: {0}", reminder);
    });
}

static void Div(int dividend, int divisor, Action<int, int> done)
{
    Contract.Requires(divisor != 0);

    var quotient = dividend / divisor;
    var remainder = dividend % divisor;
    if (done != null)
        done(quotient, remainder);
} 

In the article’s examples, an assumption was being made that the method needed to return the quotient and remainder of a div operation. The program would then continue to to run, utilizing the return values of the operation. The style Ram brought up reverses the program flow by injecting the code that utilizes the return values. Rather devious in my opinion.

Here’s my version, using a function rather than a method. I’m also using my own coding style and naming conventions.

static void Main()
{
    Action<int, int, Action<int, int>> div = (dividend, divisor, action) =>
        {
            Contract.Requires(divisor != 0);   
         
            var quotient = dividend / divisor;
            var remainder = dividend % divisor;
            
            if (action != null)
            {
                action(quotient, remainder);
            }
        };
    
    div(16, 3, (quotient, reminder) =>
    {
        Console.WriteLine("quotient: {0}", quotient);
        Console.WriteLine("remainder: {0}", reminder);
    });
}

This is the same thing as Ram’s version, except it’s an action that can be passed around. What if we make it a Func and use generics?

static void Main()
{                     
    var foo = Div(16, 3, (q, r) => q * r);
    Console.WriteLine(foo);
}

public static T Div<T>(int dividend, int divisor, Func<int, int, T> func)
{
    Contract.Requires(divisor != 0);
    Contract.Requires(func != null);

    var quotient = dividend / divisor;
    var remainder = dividend % divisor;

return func(quotient, remainder); }

To get the generic type inference, it had to be switched back to a method. It turns out that using Func makes it possible to use anonymous types without resorting to the dynamic keyword.

static void Main()
{
    var result = Div(16, 3, (q, r) => new { Quotient = q, Remainder = r });
    Console.WriteLine("quotient: {0}", result.Quotient);
    Console.WriteLine("remainder: {0}", result.Remainder);
}

public static T Div<T>(int dividend, int divisor, Func<int, int, T> func)
{
    Contract.Requires(divisor != 0);
    Contract.Requires(func != null);

    var quotient = dividend / divisor;
    var remainder = dividend % divisor;
    
    return func(quotient, remainder);
}

I believe this to be the best solution as there is type safety and a functional inversion of control. Why should someone be forced to use a DivResult class when they may not need one?

Bookmark and Share

Get Rid of out Parameters

by KodefuGuru 9. June 2010 22:38

An anachronism of the procedural world, out parameters have no place in object-oriented or functional APIs. Here are three ways to rid yourself of them.

The Example

I have created a simple program that calls a method that divides a number and returns the quotient and the remainder.

static void Main(string[] args)
{
    int quotient;
    int remainder;
    Div(16, 3, out quotient, out remainder);
    Console.WriteLine("quotient: {0}", quotient);
    Console.WriteLine("remainder: {0}", remainder);
}

static void Div(int dividend, int divisor, out int quotient, out int remainder)
{
    Contract.Requires(divisor != 0);

    quotient = dividend / divisor;
    remainder = dividend % divisor;
}

The output from this program is:

quotient: 5
remainder: 1

The method needs to return two separate values, hence the use of two out parameters. This makes perfect sense from a procedural coding style.

The Object Oriented Way

Object oriented methodology dictates that values should be represented by objects. These two integers can be represented by one value, a DivResult, which uses a small amount of memory. Therefore, I will create a DivResult struct.

public struct DivResult
{
    int quotient;
    int remainder;
    
    public int Quotient
    { 
        get 
        { 
            return quotient; 
        } 
        set 
        { 
            quotient = value; 
        } 
    }

    public int Remainder 
    { 
        get 
        { 
            return remainder; 
        } 
        set 
        { 
            remainder = value; 
        } 
    }

    public DivResult(int quotient, int remainder)
    {
        this.quotient = quotient;
        this.remainder = remainder;
    }
}

Now the program is object-oriented.

static void Main(string[] args)
{
    var result = Div(16, 3);
    Console.WriteLine("quotient: {0}", result.Quotient);
    Console.WriteLine("remainder: {0}", result.Remainder);
}

static DivResult Div(int dividend, int divisor)
{
    Contract.Requires(divisor != 0);

    var quotient = dividend / divisor;
    var remainder = dividend % divisor;

    return new DivResult(quotient, remainder);
}

Something I find interesting about this approach is that you could write a custom iterator that returns dividend and divisor pairs for the DivResult.

Tuples

The .NET Framework 4 introduces the Tuple type, which is an ordered list of elements. We need to return two integers, and this is known as a pair of ints… or in tuple terms, a Tuple<int, int>. Here’s how to do that.

static void Main(string[] args)
{
    var result = Div(16, 3);
    Console.WriteLine("quotient: {0}", result.Item1);
    Console.WriteLine("remainder: {0}", result.Item2);
}

static Tuple<int, int> Div(int dividend, int divisor)
{
    Contract.Requires(divisor != 0);

    var quotient = dividend / divisor;
    var remainder = dividend % divisor;

    return Tuple.Create(quotient, remainder);
}

Creating a tuple is as simple as calling Tuple.Create with necessary parameters. Tuples are great for returning multiple types within the context of a method or a small program. The downside in C# is the loss of context. Notice that in order to access the values, we have to use Item1 and Item2 rather than Quotient and Remainder.

Dynamic

The dynamic keyword is a new feature in C# 4 that gives us late binding. In the context of CLR types, it allows us to do something we couldn’t do in C# 3 without resorting to reflection: return anonymous types from a method.

static void Main(string[] args)
{
    dynamic result = Div(8, 3);
    Console.WriteLine("quotient: {0}", result.Quotient);
    Console.WriteLine("remainder: {0}", result.Remainder);
}

static dynamic Div(int dividend, int divisor)
{
    Contract.Requires(divisor != 0);

    var quotient = dividend / divisor;
    var remainder = dividend % divisor;

    return new { Quotient = quotient, Remainder = remainder };
}

This has the benefit of allowing us to access the properties by their name but without type safety.

Update: A commenter (Ram) posted another way of doing this. Down the Functional Rabbit Hole explores this, and in my opinion is the best solution.

Conclusion

There is no reason to use out parameters in your own frameworks. C# is still primarily an object-oriented language, and when faced with a need to return more than one result a class or struct should be created. I presented two other ways of achieving the elimination of out parameters because it may not be desirable to create extra classes when there is no opportunity for reuse.

You will need to use out parameters when interfacing with third party libraries. This is unavoidable, but the impact can be minimized by creating a proper, object oriented wrapper around the third party library.

Bookmark and Share

Responsible Extension Methods

by KodefuGuru 18. May 2010 20:47

In LINQ is Better Than ForEach, I described how to use the reduce chain refactoring to better describe the functionality of the code. By encapsulating what we were doing, the calling code became more declarative, and the the functionality was more reusable.

This didn’t sit well with one reader:

Adding such extension methods to IEnumerable<T> as you suggest is IMHO a clear violation of class responsibility. The IEnumerable is a _collection_ class. It's purpose is to manage a list/set/bag/whatever of some objects, not to access or even worse change the contained objects' state. By polluting the IEnumerable<T> with "T-specific" extension methods (e.g. DeveloperNames()), you effectively break the class contract.
Example: your Employee class changed - Role field was deleted. This means your IEnumerable<Employee> is now also broken. Why - does removing anything from the object conceptually influence anything in managing a set of those objects? No, why should it. And yet the code is broken, only because the collection class was welded to much with the items it contains.

The Cake is a Lie

I added DeveloperNames() to IEnumerable<Employee>. The purpose of IEnumerable<Employee> is to provide an interface for the GetEnumerator() method. It isn’t even to manage a list, set, or bag of employees. The only thing it does is allow you to iterate over employees.

In fact, it’s all a lie. DeveloperNames() exists in a completely separate class.

public static class EnumerableEmployee
{
    public static IEnumerable<string> DeveloperNames(this IEnumerable<Employee> employees)
    {
        return employees.Where(e => e.Role == Role.Developer)
                        .OrderBy(e => e.LastName)
                        .Select(e => e.FullName);
    }
}

IEnumerable<Employee> is not a class, it’s an interface. I created a helper, or utility, class called EnumerableEmployee. The purpose of this class is to contain utility methods for IEnumerable<Employee>. The problem is that utility classes have logical cohesion. I desired, semantically at least, functional cohesion. By using the “this” keyword, I told the compiler to treat the first parameter as though it actually owned the method.

Principles

Extension methods adhere to the open/closed principle, which states that software entities should be open for extension, but closed for modification.” By their very nature, the classes or interfaces being extended are merely parameters into a static method.

The commenter asserts I am violating “class responsibility.” The single responsibility principle states that “every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.” As stated above, the only class is a utility class that provides syntactic sugar to objects that implement IEnumerable<Employee>. In adhering with the above open/closed principle, those objects are extended.

IEnumerable<Employee> still provides GetEnumerator(). Employee[] is still an array of Employee objects. List<Employee> is still a list of employees. They never changed. The coupling is semantic and applies where the utility class is in scope.

Where Does DeveloperNames() Belong?

The reduce chain refactoring calls for placing the resulting method (whether extension, static, or instance)  in the same chain loop it originally belonged. If the original method chain was correct, this will lead to correct functional cohesion. If there is a problem, then the method should be moved, but there usually is an underlying problem to begin with.

In the case of DeveloperNames(), it started as a reduce chain on a LINQ to Objects query. Encapsulating has the following benefits:

1) makes it more declarative
2) makes it testable
3) makes it reusable with DRY

IEnumerable<Employee> represents any object that implements that interface… from an array to List<Employee> to a custom employee collection. A properly designed utility method would accept the most general interface, IEnumerable<Employee>, so any of those object could be passed in.

Polluting IEnumerable<T> with T-Specific Extension Methods

That’s been done with LINQ to Objects. One should be careful with IEnumerable<T>, since it everything can access it. Only the most general methods belong there, and most have been covered that I’m aware of. IEnumerable<[class]> should be readily extended though. The only caveat is I would try to avoid those extensions that cause side effects, if possible.

No Side Effects

The commenter states the IEnumerable<Employee> is broken, that the collection is too welded to the item. Since the code works fine, I can only assume that it is suggested the original collection is being modified.

The examples I used did not create side effects. Even after I refactored to the foreach version of DeveloperNames(), there were no side effects present, so the employee classes were not changed, and the employees instance was unaffected.

This is important, because one must be careful to only make deliberate side effects. In this example, no side effects were necessary to accomplish any task, so none were used.

var employees = new[] 
{
    new Employee{FirstName = "Chris", LastName = "Eargle", 
        Role = Role.Developer},
    new Employee{FirstName = "Mr.", LastName = "Scrooge",
        Role = Role.Manager},
    new Employee{FirstName = "Steve", LastName = "Andrews",
        Role = Role.Developer}
};

Console.WriteLine("Developer Names");
Console.WriteLine(String.Empty.PadRight(15, '-'));
foreach (var name in employees.DeveloperNames())
{
    Console.WriteLine(name);
}

Console.WriteLine("\nAll Employees");
Console.WriteLine(String.Empty.PadRight(13, '-'));
foreach (var employee in employees)
{
    Console.WriteLine(employee.FullName);
}

I ran the code with both versions of the extension method (which you can get from the original article), and the results were the same.

Developer Names
---------------
Steve Andrews
Chris Eargle

All Employees
-------------
Chris Eargle
Mr. Scrooge
Steve Andrews

I never figured out what was meant by the Role being removed. The original LINQ statement returned an IEnumerable<string>, and you would expect something similar from a method named DeveloperNames().

But still, I don’t like DeveloperNames()

My problem with DeveloperNames() isn’t for any of the reasons the commenter posted. I only used it as an example of encapsulation to maintain declarative code whether one was using LINQ or imperative code. If I were truly designing this, I believe I would make the syntax as natural as possible. I would prefer to call employees.Developers().Names(). This would also give me the ability to call employees.Names() to get the full list of names. Let’s try that out.

public static class EnumerableEmployee
{
    public static IEnumerable<Employee> Developers(this IEnumerable<Employee> employees)
    {
        return employees.Where(e => e.Role == Role.Developer);
    }

    public static IEnumerable<string> Names(this IEnumerable<Employee> employees)
    {
        return employees.Select(e => e.FullName);
    }
}

Here’s the calling code.

Console.WriteLine("Developer Names");
Console.WriteLine(String.Empty.PadRight(15, '-'));
foreach (var name in employees.Developers().Names())
{
    Console.WriteLine(name);
}

Console.WriteLine("\nAll Employees");
Console.WriteLine(String.Empty.PadRight(13, '-'));
foreach (var name in employees.Names())
{
    Console.WriteLine(name);
}

Lost now is the names in order. This can be remedied by making names always be in order, or developers always be in order. But which is it? I suppose it depends on the rules of the system.

Wait, There’s a Chain

That is right. I suppose after reducing the chain, we’ve now expanded the chain to give more flexibility. I would reduce the chain, or provide the reduced version, if an ordered Developers().Names() was frequently required.

Conclusion

There is nothing wrong with writing extension methods on IEnumberable<[class]>. As with all code be deliberate in your design so that it is semantically viable. Code should be natural to write. Avoid side effects to avoid unnecessary bugs. If you are designing a framework, make it a joy to use.

Bookmark and Share

Refactor Switch to Dictionary

by KodefuGuru 20. January 2010 14:48

In my post on Z3, I created an extension method for proving an equation. This extension method used a switch statement to analyze a result and return a string. This is a bad practice: the mapping of one type to another is trapped in code. What if I wanted to move this mapping to a configuration file, a resource file, or a database? Even if I didn’t want to do that, I feel an imperative switch statement isn’t as readable as a declarative statement. Favor Declarative over Imperative. Below is the original code snippet.

public static string Prove(this Context context, Term term)
 {
     context.Push();
     Term not = context.MkNot(term);
     context.AssertCnstr(not);
     switch (context.Check())
     {
         case LBool.False:
             return "valid";
         case LBool.Undef:
             return "unknown";
         case LBool.True:
             return "invalid";
     }
     return null;
 }

When you see case statements simply return or an assign an item, you know you can perform this refactoring. You will create a generic dictionary of both types and use it instead. Here is the refactored example.

public static string Prove(this Context context, Term term)
{
    var checkResults = new Dictionary<LBool, string>
    {
        { LBool.False, "valid" },
        { LBool.Undef, "unknown" },
        { LBool.True, "invalid" }
    };

    context.Push();
    Term not = context.MkNot(term);
    context.AssertCnstr(not);
    
    return checkResults[context.Check()];            
}

The great thing about this is that you have the mappings side by side. Since it is in a dictionary format, it is loadable from another location; the mapping is no longer tied to the code.

KodefuGuru.GetInfo()

Chris Eargle
LinkedIn Twitter Technorati Facebook

Chris Eargle
C# MVP, INETA Community Champion


MVP - Visual C#

 

INETA Community Champions
Friend of RedGate
Telerik .NET Ninja
Community blogs & blog posts

I am a #52er

I have joined Anti-IF Campaign


World Map

Tag cloud

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010