Brendan Enrick

Daily Software Development

LINQ Your Collections with IEqualityComparer and Lambda Expressions

Anyone using LINQ to manipulate in-memory collections is probably also using plenty of lambda expressions to make things quite easy. These two additions were really meant for each other. One of our interns here recently ran into an interesting problem while using LINQ. As a relatively new user of .NET based languages, reference types caused him a bit of trouble.

The problem

While using the dot notation with lambda expressions, he was using the Except method in the following way.

List<MyObject> x = myCollection.Except(otherCollection).ToList();

Well the problem here is that these two collections contain "MyObject"s, and when it does the comparison it does so based on the reference. This means if those are separate but equivalent objects that the comparison will claim they are different.

He had unit tests making sure that the except statement worked, but was using the same instance of variables to Assert, so the tests claimed to work.

I told him the problem and mentioned that there was probably an overload of Except that allows one to specify how to do the comparison. I was correct, but the overload takes an IEqualityComparer object. I was hoping for a Func<x,x,bool> as the second parameter, so I did what I always do; I Googled to see if anyone knew an easy way to get that to work without doing extra work.

The Internet was kind enough to inform me that there was no built in way of handling this situation.

Building your own was the suggestion. It is a pretty simple class, so it can just be tossed somewhere to be reused easily. It could easily come up and be needed again.

public class LambdaComparer<T> : IEqualityComparer<T>
{
    private readonly Func<T, T, bool> _lambdaComparer;
    private readonly Func<T, int> _lambdaHash;

    public LambdaComparer(Func<T, T, bool> lambdaComparer) :
        this(lambdaComparer, o => 0)
    {
    }
    
    public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
    {
        if (lambdaComparer == null)
            throw new ArgumentNullException("lambdaComparer");
        if (lambdaHash == null)
            throw new ArgumentNullException("lambdaHash");

        _lambdaComparer = lambdaComparer;
        _lambdaHash = lambdaHash;
    }

    public bool Equals(T x, T y)
    {
        return _lambdaComparer(x, y);
    }

    public int GetHashCode(T obj)
    {
        return _lambdaHash(obj);
    }
}

Now that we have a nice, Generic, comparer which can take lambda expressions, we are all set to plug this in to the previous code.

List<MyObject> x = myCollection.Except(otherCollection, 
  new LambdaComparer<MyObject>((x, y) => x.Id == y.Id)).ToList();

// or

IEqualityComparer comparer = new LambdaComparer<MyObject>((x, y) => x.Id == y.Id);
List<MyObject> x = myCollection.Except(otherCollection, comparer).ToList();

I admit I am still kind of annoyed that there wasn't an overload which just took a Func<T, T, bool> or a Func<T, T, int>.

Either way, I hope this helps someone use LINQ a little more easily. I know of some alternate ways of solving this same problem. So if you think I should have solved this differently then blog it and link back here or just post a comment below.

Update 16 April 2009 - From a comment below

One commenter below posted a suggested extension method for use with this. He suggests using this nice extension method so you can hide away the fact that you're using the custom comparer class.

public static class Ext
{
    public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, 
        IEnumerable<TSource> second , Func<TSource, TSource, bool> comparer )
    {
        return first.Except(second, new LambdaComparer<TSource>(comparer));
    }
}

Thank you for the comment. I like the idea. It will very nicely hide away the fact that a silly comparer is needed.

We Slice Software Vertically Just Like Bread

Bread When working on a feature or some other aspect of a software project, it is important to figure out what piece you want to do at any given time. There are two primary routes you could take. Perhaps you want to go and create the whole UI, but have nothing wired up. Maybe you want to go and write all the business logic first, and you might want to go create the data layer and underlying infrastructure. If you do one of those then I will call you crazy.

I believe in vertically slicing an application. You never know at the beginning of a project what scope creep is going to occur, and you also don't know which aspects of your initial design will be completely unnecessary. One of the main reasons why so many people are against "big design up front" is because we don't know what we're going to need in the end.

If we're working in vertical slices, we can complete an entire piece of functionality that we know we need. This is why we work with vertical slices. We can stop at any time, and there are no unused pieces. Everything we've completed is there and working.

If we ignore how references in our application might be set up and just look at the structure of an application with a very simplistic view, we might say that there is a UI that calls some form of business logic which in some way talks to some kind of data.

Basic Structure of a Project

ThreeLayers

Say for example that we are going to work with a horizontal slice. Yes, plenty of people do this. I tried working on an application this way many years ago. So perhaps we are thinking, "hey, why don't we get the database and the data layer hashed out at the beginning then we can just write all the code on top of it later." After working on this for a while we might end up with something like this. The blue is the completed work.

Work Done Horizontally

HorizontalWork

Now for some questions.

  • How much can we show the customer? Nothing.
  • Are we sure we structured everything the way the customer wanted? No.
  • What if this is an open source project, maybe we want to encourage other developers to join the project. Are these developers able to see the structure of our application and how we want things to work? Well it looks like.... no.

Now what if we had done the same amount of work vertically? We might end up with something like this.

Work Done Vertically

VerticalWork

Now assume that this is the same amount of work as if we had worked horizontally. Sure we have a lot less breadth, but the depth of our work is far greater. Now if we ask those same questions.

  • How much can we show the customer? Everything we've worked on.
  • Are we sure we structured everything the way the customer wanted? Yes, because the customer can see it and can tell us right now if we did something wrong. We are able to quickly respond to and fix the problem.
  • What if this is an open source project, maybe we want to encourage other developers to join the project. Are these developers able to see the structure of our application and how we want things to work? They can see everything we've done. Anyone hopping on this project would see the full structure and know how the layers are interrelated and would likely be able to add meaningful work to the project.

My Past Horizontal Mistake

So I mentioned early in this article that I tried horizontally working on a project once.  Yeah, that was a mistake. As you get to new aspects of a project a little thing called scope creep occurs. As you get to and think about new pieces of an application you realize new ways you can improve them, right? Well, this is another major problem with working horizontally. As I added new pieces, I came up with new stuff I wanted to do. New ways of doing things came to mind. Eventually I had scope creeped the data enough that I ended up giving up on the project.

I've recently started working on the project again, but this time I am of course working with vertical slices. I am going to make pieces just large enough to give me some value. That way at any point I could stop development and have a working tool. One which does something. Maybe not everything I want, but enough.

A Skill to Learn

Breaking tasks into thin vertical slices is difficult. Without advances in bread slicing technology, the processed, sliced bread from stores could never be so thin. It isn't easy to make thin slices, but the thinner the slice the better we are able to get the amount of bread we want. Perhaps we want 3 slices. Before we had these thin slices it might have been one and a half, but the thin slices make everything easier.

Some tasks look like they'll take weeks to complete. That my friend is not a task. We need to split that. There is probably some aspect of that which could be completed in a day. Maybe it wouldn't be in a shippable state, but there would be something that the customer could see. An initial bit working that is not the whole thing. This gives us two things. It shows the customer what we're working on, and it also gives them the chance to give us feedback. We can more easy adjust that small slice than if we had delivered the whole feature at once.

A Slicing Example

Assume we have a web site. We want to add user profiles to the site. Our customer comes along and says he wants the profile to have this information.

  • Full Name
  • Nickname
  • Location
  • Age
  • Gender
  • List of current and previous occupations
  • List of educational institutions
  • List of favorite games
  • List of favorite movies
  • List of favorite books
  • List of favorite songs
  • List of favorite musicians
  • List of favorite places
  • List of friends

If you went to do all of this at once it could take you a while. This is a good time to figure out some nice places to split things. An obvious split here is to do everything that is not complicated. For this we could say the top 5 ones we'll do. These don't have lists.

Slice 1: Create Full Name, Nickname, Location, Age, and Gender as a profile and create a view and edit page for them.

That slice is very manageable, and when you're done you can show the customer and make sure that is what they were expecting. Perhaps they wanted Full Name to be 3 separate pieces: First, Middle, and Last. Since we haven't done much, this is easy to change right now.

Now we might say that the next slice is the next item on the list. Why? Because we want to get one of the lists in place and the functionality set up and to the customer for feedback.

Slice 2: Add a list of current and previous occupations to the user profile.

Ok so we implement this basically as a list of strings. The user puts in the name of the occupation and adds more in the same way. We display this list of occupations on the profile page. Now when we show the customer this he says that he wants the list to intelligently suggest occupation names as the user types with previously used occupations. So now it is a bit more complicated, but we make the change. We then ask if the same will be done with the other lists, and the customer says "yes". Now we know how to do these next ones.

As we work through the next few slices, maybe the customer decides that we don't need both musicians and songs. The customer gets rid of musicians. Well we benefit here, because we hadn't put any work into that yet.

I really want to emphasize here that a slice should be small. Vertical slices are there so you always have a working product. At any moment you could stop. Maybe we stopped before doing the lists of things. We had a working solution at that moment. The other big reason we do vertical slices is so people can se what we've done and give us feedback. Customers might give you feedback on the UI, but until it is wired up and working the feedback isn't as useful.

Just In Time Properties

Properties with backing fields can easily be null. I often see properties which check the backing field to see if it is null. This is commonly done with an if statement with one line of initialization. One way to get around this is to use the coalescing operator in C#. If we use this in combination with an expressions, which might be a method, we are able to easily handle this property with one line.

Here is an example of what I am talking about.

private SomeType _someObject;
public SomeType SomeObject 
{ 
    get 
    { 
        return _someObject ?? (_someObject = giveMeSomeObject()); 
    } 
}

Notice how short and concise this is. I am able to with one line which is very clear handle this common scenario. Sure it doesn't always match this exactly, but I see plenty of properties people write where they do something similar.

I think that is very elegant and a lot nicer than doing this older style.

private SomeType _someObject;
public SomeType SomeObject 
{ 
    get 
    { 
        if (_someObject == null)
        {
            _someObject = giveMeSomeObject(); 
        }
        return _someObject;
    } 
}

Getting Around a Lack of Interfaces With Partial Classes

One pain point which comes along often when working with others' libraries are the classes that are not open and implementing interfaces. A lot of the classes we developers use every day implement no interfaces. Since the class is out of my control, I obviously cannot give it an interface, so I need some other way to work with it. This creates a problem when we need to mock out the class. There are ways in which we can get around this though.

Wrapping Classes

In my opinion, the most dependable workaround to be able to mock out and test a class is creating an interface-implementing wrapper around the class we want to mock and using that instead. This one works very well, but it forces you to create an interface and a class even though there is already a class in existence.

Partial Class Interface

As the name of this post says, partial classes can be very important when presented with this problem. If a class is not implementing an interface, but it is a partial class, you can give it an interface it is already implement.

If a class is partial you can give it an interface which defines the methods it already implements.

So now I am going to present an example. For this example, we will have a class called "BrendanMailer". This class is not implementing an interface, which means that if we want to remove this dependency we need to come up with some solution that lets us program against an interface.

public partial class BrendanMailer
{
    public void SendEmail()
    {
    }

    public void SomeNonImportantMethod()
    {
    }
}

For this we could obviously use the wrapper method, but we can also do something a lot easier. Thanks to the smart creator of that class, there is a partial keyword in there. This allows us to leverage a very powerful trick, because we can now create our own interface. The interface can include only the methods we want it to, which is in some ways better than if the interface had been predefined.

public interface IBrendanMailer
{
    void SendEmail();
}

So now I have a custom interface to work with and program against. I now just add that into another part of this partial class and tell that one I am implementing the interface. I don't have to implement the methods, because they already are implemented in the original part of this partial.

public partial class BrendanMailer : IBrendanMailer
{
}

In my production code I will inject the BrendanMailer class, and in the tests I will mock it out or use a fake or something. This is very powerful and doesn't clutter much at all, because I can hide this partial away in a folder in my project and ignore it for a long time.

Recent Article Writing

Over the past month, I've written a few articles for ASP Alliance. I now need to shamelessly plug my own stuff. If I didn't post this kind of stuff on my blog, I wouldn't really be doing my job. I wrote these articles so people could read them, and linking to them here should help with that. Enjoy.

Standard Type Casting and "as" Operator Conversions

In early February, I wrote this article, which discusses in fairly easy to understand language when, why, and how to use each of these types of conversion. I am hoping that anyone who doesn't know the difference or doesn't know when to use each one, learns a little bit more about that from this article. I tried to keep things fairly basic, so people could really understand this well.

Read more about Type Casting and "as" Operator Conversions

Using Objects Instead of Enumerations

I love enumerations, but they have caused me plenty of pain in the past. Why did they cause problems for me? Well, that is because I shouldn't have been using enumerations. I've seen plenty of people doing the same thing. Sometimes you really just need to have a class instead of an enum. However, if you really do need a restricted set of values, you can use private constructors to create the only allowed instances of this object as public properties. I tend to move to this type of object as soon as I need a description, a friendlier name, or any additional logic for my enumeration.

Read more about Using Objects Instead of Enumerations

Beginning Test Driven Development

Lately a lot of people have been trying to learn how to test their applications, but I think there is a fairly significant learning curve preventing people from getting to that point. I am planning on writing some related articles to this one which start pulling together the different aspects of testing. I will probably be discussing Dependency Injection, Mocking, and Inversion of Control at some point. For this article I focused mainly on how to write tests. I know a bunch of people who are trying to get started testing, but don't know how or what to test.

Read more about Beginning Test Driven Development

Let me know what you think about these articles. As long as you're nice about it, I always like getting feedback; even feedback pointing out problems in the articles.

Treat Your Tests Well

There are a lot of people starting to test, and some of them seem to have this misconception that test code is less important because it is, "just test code". I don't know how they come up with this crazy idea, but it creates some pretty ugly tests. When following the principles of Test Driven Development, it is important to realize that you will come back to these tests. You will look at them when they fail, you will adjust them when logic changes, and others will read them especially when they are trying to learn the system.

Maintenance

At some point you could perform maintenance on any piece of code in your application. THIS INCLUDES YOUR TESTS. When you need to go in and change them it better be easy. There better be code reuse, variable names better be descriptive, and you really need to have things organized well enough for you to find what you're looking for.

Single Responsibility Principle

The Single Responsibility Principle is a commonly followed principle when writing code, but I've seen people disregard it when writing tests. Your tests are extremely important. Don't make huge catchall test classes. Keep your test classes small and manageable. Each one should contain only a related group of tests. You will come back to these if you're testing correctly, and when you make changes you will write new tests or adjust old ones. Don't think for one second that you will never see your test classes after you write them. When you add new features and adjust old ones, you will need to open these files again.

Test code is a first class citizen in your project. It is every bit as important as the rest of the project. Treat it as such or it will bite you back.

One Way Tests Differ From Other Code

With tests, the specific details are a little bit more important than in other code. You still need code reuse for obvious reasons, so what do I mean here? All I am saying is that you don't want to hide things away in mysterious methods. Normally we extract methods to hide the details of some operation we are performing. We should be doing the same thing with test code, but we need to make one exception. When the details of that method are what you're testing, you must have them in your test.

In some instances you have an object with involves some complicated or at least tedious initialization, so you would want to hide that away in a method. For testing, however, it is important that you define the details of that initialization in the test method if they are important to the test.

As an example, we can say that we are working on a game, and we keep a Points property on our Player object. Maybe we want to make sure that after some action that would lose a player points, he doesn't go below a negative number. So we have a method that creates a player object for us. The problem is that we don't know what his initial points are set to if we don't either make that a parameter in the initialization method or set it after initialization. In some way we need to make sure that we define this in our test method.

Never ever let details you depend on be hidden away in some method where you can't see them in your test.

I've seen plenty of people use helper methods to initialize variables and such for their tests. This is a very bad idea if any of that information is important to that specific test. Only hide away unimportant details. For instance you might hide away the initialization of your mocked objects, but you would keep the player's points you will be Asserting the value of front and center. If values are being initialized in a non-test method you should be able to change those tests safely without causing problems.

Treat your tests well and they will be there to help you.

Organizing Software Projects

Managing and structuring software applications is a complicated topic. Many different ways of structuring applications exist, and there are merits to several methods of organization. In this post, I am going to roughly describe a method of organizing a software application to which I am somewhat partial.

One of the most important aspects of a well-organized project in my opinion, is the ability for a new developer on a project to be able to sit down and have a working solution as soon as they get the latest version of the application from the source control repository. Not only should that person be able to have a working solution, but that working copy should assist the developer in setting up the local environment. The solution should also be in a state which allows all of the project's tests to run without the user having to jump through a bunch of hoops.

Being able to sit down and start working immediately is very powerful. We wouldn't be able to achieve this without first having things packaged and tested nice. We are allowing anyone to figure out how things work based on the logic standardized and explained by our tests. The developer is now able to make meaningful, useful changes to the project right off the bat by making modifications and testing them. As long as they're not breaking existing tests, they can have some confidence that they're meaningfully contributing to the project.

Combined with continuous integration we are able to know that the project is in a tested, working state, and when we check out the source for the project, that it should work correctly already. There are a few pieces which must be in place in order for this to work. We need to make sure that the class libraries we're depending on are included in relative paths in the source control repository, so we don't have to worry about whether or not they are installed on the developer's machine. We also need to make sure that we have the project sufficiently well tested. Build scripts are also vital in allowing someone to sit down and start working immediately.

When deciding what tools to use for testing and for your build scripts, it is important to decide which tools you can safely assume will be on the developer's machine. As far as I know, you can't package MSTest or MSBuild along with your project. If everyone who uses this code will have these, then it is perfectly acceptable to depend on them. If that is not the case, I would recommend using NUnit and NAnt. These tools are very similar and are easy to use. Their integration with Visual Studio is not as nice, but they are easier to have dependencies on.

The trunk looks somewhat similar to this.

trunk-explorer

See that at this first level of the application, we have very little clutter. Things should be kept neat and tidy here, so that people just checking this code out aren't overwhelmed by anything before opening this. The lib folder contains class libraries that the project has dependencies on as well as the tools for building. This includes things like NUnit. By keeping it out here we are starting off having the opinion that these should be kept at arms length the whole time while working with the project. The less our dependencies integrate with our source the better off we are.

src-explorer

At this level inside the src folder, it is important to see that we still haven't shown any of our clutter. We of course get a lot more cluttered once we see the source code. I don't mean that the code is messy, but seeing a dozen files is a lot messier than a handful of folders and a solution. At this level someone can open up the solution and see the project from within Visual Studio already knowing that the solution works. How do we know it works? We ran the BuildAndTest file and it made sure that the project built and that all of the tests passed.

That little addition of having the ability to build and test the project is so valuable, because in a moment anyone can know if the project is working. We get quick feedback without even having to load visual studio. We don't have to search for the files among others; they're right there on their own.

Good luck, good organizing, good testing, good night.

And now an opportunity to promote Jeffrey Palermo's class. If you are interested in learning about Agile software practices, I recommend taking the Agile Bootcamp class offered by Headspring Systems. I learned a great deal from that class, and a lot of the practices I currently use are adaptations of what I learned. It isn't a class that tells you exactly how to do things, it shows you a way of doing things that works, which you will be able to take and adapt to how you're already working.

Silverlight Attached Properties

One cool feature of XAML is the concept of an attached property. These properties are a way of extending the properties of an element in XAML. By this I don't mean that you can add any arbitrary extra property to an element. What I mean is that child elements have certain properties from their parents attached to them. This is often used as a way of allowing a child element to interact with a parent.

A couple of examples of what I mean can be found in the DockPanel and the Canvas elements. Some attached properties you will find from the Canvas element are Canvas.Top, Canvas.Left, and Canvas.ZOrder. These three let you control the location of the child element within the canvas. A DockPanel element gives DockPanel.Dock, because it is important to know where on the DockPanel your child element is docked.

You have probably noticed by now the naming of these attached properties. They are named in the following way.

ElementName.PropertyName

Here are some examples of how to use these.

<DockPanel>
  <Button DockPanel.Dock="Left"/>
</DockPanel>

<Canvas>
  <Ellipse Width="100" Height="100" Fill="Black"
    Canvas.Left="25" Canvas.Top="25" />
</Canvas>

Notice I've docked the button to the left of the DockPanel and the Eliipse has been positioned away from the left and away from the top of the canvas.

It would be a nightmare to try to control positioning of elements inside of the canvas anywhere but on the specific element, and the attached properties allow this to happen. I think they are quote cool.

Windows Home Server Becoming Available on MSDN

windows-home-server Earlier today I went looking to see if MSDN included Windows Home Server. Well, it doesn't include it. I looked in the "servers" section, the "operating systems" section, and when that failed I asked Google. I read the Official MSDN Subscriptions Blog, which contained a post about Windows Home Sever. It seems that including Windows Home Server was considered and rejected. Thanks to the post on that blog, a lot of feedback was received requesting its inclusion as well as information about why it was not included. Thanks to an update on that post, I know that a year ago they said they would be reconsidering it based on the feedback.

I still don't see it as an available download, but luckily there has been follow up information on the issue. Philip Churchill posted about WHS Coming to MSDN a couple of months ago. Now, I sit around waiting for Microsoft to deliver this awesome product to their faithful MSDN crew. I just used one recently, and it is very easy and nice to use. I now see what all of the hype has been about. For once I think the hype was not exaggerating the product. At least not much.

I look forward to the release of Windows Home Server on MSDN. I hope you do also, since I will most certainly write about it once they release it.

Converting an Array of Integers int[] to an Array of Strings string[]

I was working on a code snippet I plan to put into a blog post, and while writing it I needed to convert and array of integers to an array of strings. I try to think of a quick easy way to do this and none comes to mind. Well, I of course know that I could just loop through them and convert them from ints to strings, but that is really lame especially when I want the code to be small so I can put it in a blog post.

So there are a few options that present themselves when you are looking for a method to help you out.

  • Write your own method to solve the problem. (I try to only do this as a last resort. I try to use existing code when possible.)
  • Ask Google (or any other search engine) for answers posted on forums, blogs, articles, documentation, etc.
  • Go ask/search on a forum or a Question and Answer site.
  • Use intellisense and check some related classes which may hold the answer.

In this instance I used the last one. I checked out some classes using intellisense to see what methods were available. I was working with arrays, so the one I checked is the Array class. Array.ConvertAll is what I needed.

var intArray = new[] {1, 2, 3, 4, 5};
string[] stringArray = Array.ConvertAll(intArray, i => i.ToString());

That is roughly how I am using it in my code. Notice the nice lambda way of handling the individual object conversion. You can also solve the problem using a full-fledged method call. I just chose this to keep things more compact.

Here is an example using a method to hide the lambda and do the conversion.

static void Main()
{
    var intArray = new[] {1, 2, 3, 4, 5};
    string[] stringArray = Array.ConvertAll(intArray, IntToStringConverter());
}

private static Converter<int, string> IntToStringConverter()
{
    return i => i.ToString();
}

As usual there are still many other ways to do this, but I'll show you one that just has way too much unnecessary code.

I don't recommend using this example since it really just specifies way more than it needs to. I am just including this to illustrate the many ways to have solved this problem using this same method.

static void Main()
{
    var intArray = new[] {1, 2, 3, 4, 5};
    string[] stringArray = Array.ConvertAll<int, string>(intArray, 
        new Converter<int, string>(IntToStringConverter));
}

private static string IntToStringConverter(int n)
{
    return n.ToString();
}

Why don't I really like that one? Well to be honest I intentionally made it bad. The "new Converter<int, string>()" part is completely useless. You can remove it completely and the code still works, because we specified already that we are doing int to string. We alternatively could have removed the first <int,string>.

Although if I were using an older version of C# I would be forced to use the last one, or I could also use a combination of the second and third one.

Well, we're out of time here today. I hope you've enjoyed this edition of Finding Stuff Using Intellisense. This is your host, Brendan Enrick. We've been glad to have you with us today. Join us next time when we....  Find Stuff Using Intellisense. {queue the ending theme music}

Brendan Enrick | Where Should Test Classes Go?

Brendan Enrick

Daily Software Development

Where Should Test Classes Go?

LegacyCodeBook In Working Effectively With Legacy Code, the author talks about where to place test classes in your applications structure. He mentions that you should place test classes along side production code in the structure of your application. Why? Well he says that it is good because it helps you navigate between the test classes and the production code easily.

I somewhat agree with him when he says this, because a lot of time is wasted moving between classes. I admit I am one of the people who tries not to mix too much test and production code. I like to keep anything test related at arms length. Why do I do this? Because I believe that everything becomes cleaner and easier to observe when it is separated. I believe there is some reason to keep things aesthetically pleasing, and I certainly believe that keeping them separate will make the system appear a lot less daunting.

Navigating Between Test and Production Code

So I've explained what I like about keeping the two together, but I still haven't made an argument for why I don't need the "navigation" benefits of keeping the two together. The way I handle this is through superior add-ins to my IDE. I use Resharper to give me better navigation. Lately I've become quite fond of this application. If nothing else just for the ability to navigate to classes and files in the solution based on the name alone.

GoToType1

This is incredibly powerful, and it is a quick keyboard shortcut away. It lets you navigate quickly and easily. I like it because it lets me organize how I want to, and I don't need to worry about moving from one assembly to another even. I keep my unit tests in a separate project from any production code. Since I can still navigate quickly, I get all the benefits of both methods.

I think there are a lot of great suggestions people can make for how to code, but at the end of the day you need to make your own choice. Consider people's suggestions, understand why they make them, and certainly adjust them to your own uses.

My opinion is that test classes should go in a separate location. It keeps the production app less cluttered. The application will not deploy test code. If they're separated there will never be any confusion. It would just be terrible if you had a class that actually needed to have the word "test" in the name.

Loading