No More Magic Strings! Presenting: @string.of

17 בנובמבר 2010

תגיות: , , , , ,
8 תגובות

The Problem

How many times have you seen the following code snippets?

1. Checking method parameters

if (executeMethod == null)
{
    throw new ArgumentNullException("executeMethod");
}

2. Implementing a property in a WPF / SL view-model

public double Size
{
    get { return _size; }
    set
    {
        _size = value;
        RaisePropertyChanged("Size");
    }
}

The first time I had to wrote code like this I felt uneasy. Hardcoded strings are bad practice and should be rarely used.

Even worse, using a hardcoded string of an identifier is just a bug waiting to happen.

Consider what happens when you need to refactor your code and change the name of the Size property (second example) to something different like MaxSize.
The refactoring tools will not change the hardcoded string “Size” and now your WPF application stops notifying on property change the way it should!

These bugs are very difficult to spot. No compile time error, no runtime error. Nothing. The only way to spot this bug is by testing this specific functionality.

I’ve checked a small WPF application and found 158 (!) instances of these
almost-bugs.

The Solution

Are you familiar with the typeof operator?
Don’t you just loved it if there was a stringof operator?

Well, there isn’t!
So I’ve implemented the closest thing: @string.of()

To use it simply write:

string s = @string.of(() => Size);

Since the implementation uses expression trees the syntax might look strange, but as I’ve said, that’s the closest you can get without being a member of the C# development team.

Here you can find a full example that uses the @string.of operator on various inputs: local variable, parameter, property, field and function.

That’s it for now,
Arik Poznanski.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

8 תגובות

  1. Gamlor18 בנובמבר 2010 ב 18:53

    Hey, good idea. For the notification I'm using a special extension method which does basically the same. It also works with lambda-expression. (see: http://www.gamlor.info/wordpress/?p=832)

    But your utility is even more versatile. Cool.

    להגיב
  2. nelson18 בנובמבר 2010 ב 19:41

    http://thedailywtf.com/Articles/Soft_Coding.aspx

    Also, ReSharper will detect any string literals inside of a property and ask you if you want to refactor them as well (just tested on VS2010/ReSharper 5.1).

    I'm not saying that your code is a bad idea, I think it's really cool. Though I'd be interested in knowing the performance of that method invocation.

    להגיב
  3. Adnilson Soares22 בנובמבר 2010 ב 15:10

    Thank you. @string.of will help me a lot.

    להגיב
  4. who i am23 בנובמבר 2010 ב 22:05

    i like this stuff tnks for share
    btw i know u from sela

    להגיב
  5. Omer Raviv27 בנובמבר 2010 ב 19:50

    Hey Arik,

    That's a cool idea! Nice!

    Hope you're having a good time :)
    – Omer

    להגיב
  6. Omer Raviv29 בנובמבר 2010 ב 18:31

    Hey Arik, a couple of comments –

    1. I found it a bit confusing that Of is implemented as an extension method of String. I think it would be easier to understand what's going on if it was implemented as a simple static method, something like "GetString.Of", where GetString is a static class.

    2. As nelson already asked, I'd like to know if you benchmarked this, and if there are any performance consideration to take into account before using this in production code.

    Thanks!

    להגיב
  7. arik29 בנובמבר 2010 ב 18:58

    Hi Omer,

    1. The Of method is NOT an extension method of string.
    The class @string has a simple static method Of.

    2. Haven't checked it yet, since I haven't had the time.
    But if any of you check it I'd be happy if you post your results.
    Surely, it's slower, but the question is does it makes a difference.

    IMHO, if you have something that changes a property 1000 times a second, maybe you are doing something wrong anyway..

    להגיב
  8. Brandon25 באוגוסט 2011 ב 21:48

    Maybe I am missing the point here. Your code is cool, but where does this help me in a real life scenario?

    להגיב