Skip to content

Instantly share code, notes, and snippets.

@gshutler
Created December 9, 2010 13:15
Show Gist options
  • Select an option

  • Save gshutler/734701 to your computer and use it in GitHub Desktop.

Select an option

Save gshutler/734701 to your computer and use it in GitHub Desktop.
public interface IHeader
{
string Value { get; }
IEnumerable<string> Values { get; }
}
public sealed class Header : IHeader
{
readonly IEnumerable<string> values;
readonly string value;
public Header(IEnumerable<string> values)
{
this.values = values.ToArray();
value = this.values.FirstOrDefault() ?? string.Empty;
}
public string Value
{
get { return value; }
}
public IEnumerable<string> Values
{
get { return values; }
}
}
@tt
Copy link
Copy Markdown

tt commented Dec 9, 2010

Say you have two collections like this:

IDictionary<string, IHeader> Headers
IDictionary<string, IEnumerable<string>> Headers

Both of these allows the dictionary to return a null, so I don't think null is a valid reason for deciding on either of these.

Naturally, the sequence can be empty in the last case causing .FirstOrDefault() to return a null, but I don't think null is a terrible value for a string, and especially since you'd never return anything for an undefined header in the first place.

@gshutler
Copy link
Copy Markdown
Author

gshutler commented Dec 9, 2010

You could specify that the IDictionary<string, IHeader> cannot return null, which I'll add, particularly as this is not a valid thing to do with headers. This then eliminates the presence of null at both levels making the header dictionary much easier to work with.

@tt
Copy link
Copy Markdown

tt commented Dec 9, 2010

... but why can't you specify the same requirement for a IDictionary<string, IHeader> property?

@gshutler
Copy link
Copy Markdown
Author

gshutler commented Dec 9, 2010

I'll assume you meant IDictionary<string, IEnumerable<string>> there and restate what I tweeted for completeness of this conversation.

For a given header you will know how many entries there could be. Having a retrieval method for each scenario removes complexity. Not having to worry about null removes complexity. Putting a little effort into how headers are stored and retrieved will help everyone who interacts with this collection.

I realise it's not the simplest solution but there will realistically be one implementation of this so getting it right is worth the effort.

@gshutler
Copy link
Copy Markdown
Author

gshutler commented Dec 9, 2010

I'm going to sketch out some code that actually uses this over the weekend to see if what are gut feelings at the moment are realised.

@tt
Copy link
Copy Markdown

tt commented Dec 9, 2010

I'll also restate my latest reply then :-)

Given the host header, one could use Headers["host"].Single(). To me, this reads out clear and will neither yield a null from the dictionary or an InvalidOperationException from the sequence, if the requirement is to always provide a single item enumeration (I'd actually prefer it to yield a null, but that's another discussion).
So, whether you have to handle a null will be a detail of the implementation in both cases.

I think we pretty much agree on what is best and what is most practical. I guess I'm just more idealistic about how I would design a framework. As an example I'd prefer extension methods for making it easier rather than introducing multiple ways of achieving the same in the interface.

@gshutler
Copy link
Copy Markdown
Author

gshutler commented Dec 9, 2010

It could be that trying to wedge my idea into a generic container is a bad idea. I'll write some code and try some ideas out. It could be I go back to IDictionary<string, IEnumerable<string>> or it could be I end up at a specialized IHeaderCollection.

I'm against being reliant on extension methods for completely standard interactions. They aren't discoverable if you don't have the right namespace imported and force you to use methods rather than properties or indexes.

Thanks for your feedback by the way, it's much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment