tags:

views:

804

answers:

11

Is there a way to make this line shorter?

bool pass = d != null && d["k"] != null && (bool)d["k"];

Note: "k" is actually "a longer id"; I replaced it to make it more readable in this post. Many of your suggestions don't check whether d is null.

+30  A: 

It is already barely readable, so why make it any shorter?

Andreas Grech
Agreed. If anything it should be longer, or at least use better variable and index names.
Welbog
Agreed- what do d and k represent?
RichardOD
Where is the connection? Making it shorter could potentially *improve* readability. Compare `x == null ? "foo" : x` to `x ?? "foo"`. Short == (potentially) concise.
Konrad Rudolph
Robin Day
To improve readability maybe? Shorter doesn't always mean more cryptic.
Adrian Godong
+8  A: 

I would question why you are trying to make it shorter.

Shorter code doesn't benefit anybody. It makes it far harder for someone else to read it.

Personally, I would be asking "how can I make this code easier to read", and the answer to that would be split it up into multiple lines, and only do 1 thing on each line.

The only 'null shorthand' available in C# is the null-coalescing operator, which allows you to define a default value for a null object. But for your code, I'd recommend aiming for readability, not line size.

Simon P Stevens
Maybe shorter code implies faster code? :D
Adrian Godong
@Adrain: Maybe....and maybe I write my code in assembly....maybe I don't...
Simon P Stevens
Because the frequent "null" checks get on my nerves, too.
peterchen
+2  A: 

I would question why you are casting d["k"] to a bool. Either it is already a bool or it should be compared to something to get a bool. This would make things clearer.

Anyway, I suppose this might work:

bool pass = (d != null) && d["k"] ?? false
Patrick Szalapski
+11  A: 

Try this:

bool pass = d != null && (bool)(d["k"] ?? false);
Anton Gogolev
Thats much nicer :D
acidzombie24
+1 I think this is what he was after, the ?? operator. Still needs the check for d as null as well though. I've always thought it'd be nice to have a cascading ?? operator, however, I can see plenty of reasons why it would be bad!
Robin Day
This does not check if the value in the dictionary exists. If crashes on a null-ref exception if "k" is not there.
Jan Zich
@Jan No, it does not. If d["k"] returns null, right-hand side of a ?? operator (which is "false") gets converted to bool.
Anton Gogolev
Sorry, I meant the "key not found" exception.
Jan Zich
Jan, if Anton's code crashes, then so did the original code. That's not the point of the exercise.
Rob Kennedy
+4  A: 

Yes, extract a function from it and call it something like doTheValuesInTheFooBarDictionaryPassTheRebarTest.

That's much easier to read. Of course, the method will still contain your line above, but the reader of the code (from here 'till the end of time) will have a MUCH more pleasant experience when skimming the code.

By making code shorter, what are you hoping to achieve? Quicker to read? (it'll take longer for the brain to parse it!). Quicker to type? (you type this stuff once and either modify or read it again and again (and again!)). Generally, longer, more descriptive variables are better, and if you can wrap them in an encapsulating method, then do that too.

Steve Dunn
Not a fan of extracting a 1-liner into a method with a name that's even harder to read than the one line of code, but the concept is valid for other cases.
James M.
I am with Steve here. Giving name to such one liners are very useful when you are reading the code. And yes, the name suggested by the Steve is an example and not the actual name.
SolutionYogi
James, it's a 1-liner OF TEXT. Logically, it's a multi-liner: Does this thing exist AND if it does, does it contain a particular field AND if it does, try and coerce it into a boolean value. Without extracting a function, you'll be continually parsing ALL these things (the HOW) rather than just browsing an overview of what you need (the WHAT)
Steve Dunn
+4  A: 

You can get rid of the first expression by initializing d in the constructor. I recommend you to use generic dictionary i.e.

Dictionary<string,bool> d = new Dictionary<string,bool>();

That way you don't have to cast the value. And use the ContainsKey method as opposed to directly accessing the value. So your final expression

bool pass = d.ContainsKey("k") && d["k"];
Vivek
+1  A: 

This is not shorter, but more reliable (and perhaps a bit more efficient):

bool pass = false;
if (d != null)
{
    object value;
    if (d.TryGetValue("k", out value))
    {
        pass = value is bool && (bool)value;
    }
}

I would recommend moving it into a function.

Jan Zich
+2  A: 

Yes. Make d strongly typed (e.g. use Dictionary<> instead of Hashtable)

bool pass = d != null && d["k"];

It would help if we knew the type of d!

Matt Howells
+1  A: 

You could replace it with a function call that takes in a dictionary and a key...

Brian
+3  A: 

I would not try to shorten it further, I would try to give it a nice name. Writing an extension method or modifying the class (if you have access to the code) sounds good to me.

// Better use a longer and more descriptive name here.
public static Boolean Pass(this Foo foo, String bar)
{
    return
        (foo != null)
        && (bar != null) // Maybe this test, too?
        && (foo[bar] is Boolean)
        && (foo[bar] as Boolean);
}

And use it like that.

Boolean pass = d.Pass("k");
Daniel Brückner
+1  A: 

I would much prefer to see something like this:

bool pass = false;
if(d != null && d["k"] != null)
  pass = (bool)d["k"];

or if wanted to write a handy extension method for System.Object that would make it look like this:

bool pass = false;
if(!d.IsNull && !d["k"].IsNull)
  pass = (bool)d["k"]

I find this much more understandable than the original version.

John Kraft