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}
I was looking at a piece of code recently and noticed that someone was checking for a null parameter and throwing an ArgumentException, so I figured since ArgumentNullException inherits from ArgumentException I would just replace it with the more specific exception. Little did I know that Microsoft has a wee little bit of a problem with consistency on these.
With ArgumentExceptions it is important to have a message as well as specify which parameter is causing the trouble, so there are 2 string parameters in the ArgumentException constructor. What you might not know if you haven't switched one to the other is that they changed the order of those parameters. What I mean is that you call them like this.
throw new ArgumentException("The Message", "paramName");
throw new ArgumentNullException("paramName", "The Message");
throw new ArgumentOutOfRangeException("paramName", "The Message");
How can they possibly switch those?!?! If I am not mistaken the lower two exceptions actually inherit from the first one, so it is quite surprising that the ordering was not maintained in the second two. I need to keep an eye out for other such inconsistencies while I am working. They obviously can't easily fix it now, because too much code depends on the current ordering. I try to maintain consistence parameter ordering, but I am also not working on a framework.
While reading an article, I came across a misconception that seems all too common with people using ASP.NET, and they need to stop trusting intellisense!!! I love intellisense, but you can't trust in it entirely. It doesn't know everything, so as a rule, I will state that if html supports something... SO DOES ASP.NET!
So now that I am done ranting I first want to say I am not intending to bash the author or the publisher site. Both have some great content and are valuable to the .NET community. I simply want to step in and provide some clarity by providing some explanation and an alternative solution to the problem. The article is about adding a tooltip to individual items in a dropdown list. There are plenty of reasons to do this, including the one the author states which is that the list might have a fixed width and will display badly in IE. Below is an example of a DropDownList with this problem.
That is a terrible UI problem right there. I personally prefer the way Firefox handles this situation, but aside from that we might want to use a tooltip anyway.
The thing that seems to throw everyone off is that some ASP.NET controls don't seem to have many properties when you look at intellisense. A lot of them don't include style, title, or some other commonly used attributes. THEY ARE STILL THERE!! Underneath the hood ASP.NET is basically just the HTML you know and love. So when you go in and try to add the title attribute to a ListItem, you will not see it in the intellisense box.
The article suggested doing a foreach loop over the Items in the DropDownList and edit their title property. Well, you can actually just set the title property. ASP.NET will give you a warning about it because it isn't an ASP.NET attribute, but it will work.
I would also like to mention that this also works with the style attribute. I've heard plenty of people complain that some controls don't support the style attribute in ASP.NET. If their underlying HTML control supports a tag it supports a tag. For this example since the option tag supports the title attribute it means that the ListItem of a DropDownList also supports the attribute.
In his article he does one great thing showing people that it is very easy to make changes to the html by simply using the Attributes collection of any control in the code behind an ASP.NET page. Using this allows us to alter any attribute we wish. One thing you need to be careful of is the ease through which we are able to add duplicate attributes or cause other problems by this.
In his article he uses the following line of code to add in the title attribute.
_listItem.Attributes.Add("title", _listItem.Text);
If the above code were to somehow run twice it literally would add two separate title tags into the HTML which is not always the best way of handling things. Just figured I would throw this out there so people have a better understanding how the connection between ASP.NET and HTML. Some people try to separate ASP.NET as some new thing when at the end of the day it is really just creating HTML. Don't let ASP.NET be mystical, it is relatively easy to understand if you just read articles and blogs. Be curious and questioning of everything. Yes, I mean for you to question what I tell you also. Plenty of things I write over a long period of time will be questionable and some will just be outright wrong. Everyone will do it. Yes, even people writing documentation.
If you've ever gone to a conference and not known what to do on the first night, you should check out Party with Palermo. Hosted by Jeffrey Palermo, these parties are a good time. Free finger food, free swag, and free drink. The next one is for Alt.Net and the MVP Summit. On the first day of March 2009 from 7:00 PM until 10:00 PM the party will be at Jillian's 731 Westlake Ave N, Seattle, WA 98109.
The event is fun and easy to attend. Palermo wants people to RSVP on his site. Even if you don't respond, you can still show up. The price of admission is one business card. It is easy and will give you a fun event to attend.
If you are not going to be there at that time, don't worry there will be other parties with Palermo later.
While working with an entity object I wanted to validate, I took some time to do some Googling. I was planning on creating an IValidator<T> interface so I could keep the validation separate from my classes, and I was going to implement this interface for every entity that needed it. Since validation is pretty common I figured I would take a look around first to see if there were some good ways of performing validation which differed slightly from how I had done things previously or offered any insight on a good solution similar to what I mention above. I found a link to a blog post that had exactly what I was looking for. It turns out that Jimmy Bogard already had a great post on this topic. His post, Entity validation with visitors and extension methods, demonstrates a very cool IValidator implementation.
He combines a couple of cool interfaces to get this working. He uses an IValidator<T> interface like I mentioned I wanted to use. His implementation of this is pretty nice. (I made a slight adjustment to it here, because his example code had a bug.)
public class OrderPersistenceValidator : IValidator<Order>
{
public bool IsValid(Order entity)
{
return BrokenRules(entity).Count() == 0;
}
public IEnumerable<string> BrokenRules(Order entity)
{
if (entity.Id < 0)
yield return "Id cannot be less than 0.";
if (string.IsNullOrEmpty(entity.Customer))
yield return "Must include a customer.";
yield break;
}
}
I look at this an see a fairly nice and elegant solution to the validation problem. He also has an IValidatable<T> interface he uses, which is nice because it sets up a method to pass in the IValidator to use.
public class Order : IValidatable<Order>
{
public int Id { get; set; }
public string Customer { get; set; }
public bool Validate(IValidator<Order> validator, out IEnumerable<string> brokenRules)
{
brokenRules = validator.BrokenRules(this);
return validator.IsValid(this);
}
}
So I think this code is pretty cool, but the only thing that was still irking me about this code is that now I would have to pass the IValidator object in to the Validate method of the entity. I really don't want to have to pass those in, so I start thinking about how to get around that problem. Well then I just read a little further in his article. He has a very nice solution to this problem using an extension method on a Validator class. (I adjusted this snippet slightly also, because it too had a bug.)
public static class Validator
{
private static Dictionary<Type, object> _validators = new Dictionary<Type, object>();
public static void RegisterValidatorFor<T>(T entity, IValidator<T> validator)
where T : IValidatable<T>
{
_validators.Add(entity.GetType(), validator);
}
public static IValidator<T> GetValidatorFor<T>(T entity)
where T : IValidatable<T>
{
return _validators[entity.GetType()] as IValidator<T>;
}
public static bool Validate<T>(this T entity, out IEnumerable<string> brokenRules)
where T : IValidatable<T>
{
IValidator<T> validator = Validator.GetValidatorFor(entity);
return entity.Validate(validator, out brokenRules);
}
}
This Validator class reminds me a lot of IOC stuff. You register a validator with the entity type it validates. This lets you set up which validators each class needs so you don't have to specify on use. It also provides a nice extension method which allows you to call the validate method without having to pass in the correct validator. It will use the one it has registered for that entity type.
Great solution in my opinion. Now I am going to add his blog to the blogs I read. I hope some of you do also.