12

I have 2 objects, both of which I want to convert to dictionarys. I use toDictionary<>().

The lambda expression for one object to get the key is (i => i.name). For the other, it's (i => i.inner.name). In the second one, i.name doesn't exist. i.inner.name ALWAYS exists if i.name doesn't.

Is there a lambda expression I can use to combine these two? Basically to read as:

"if i.name exists then set id to i.name, else set id to i.inner.name".

Many thanks.

Update

When I say "don't exist", I mean the objects don't actually have the properties, not that the properties are just null.

4
  • 1
    If you say that the properties don't exist, do you mean that the objects actually don't have the properties, or that the properties are just null? Commented Mar 19, 2010 at 11:00
  • The objects don't actually have the properties. Commented Mar 19, 2010 at 11:04
  • So then these two types are two completely unrelated types then? Commented Mar 19, 2010 at 11:11
  • @shf301 yes. However, all of them either have a name property, or a object.name property of type string. Commented Mar 19, 2010 at 11:31

5 Answers 5

14

If these are two distinct (reference) types then you can test them using the is or as keywords:

i => {
         var x = i as TypeThatHasNameProperty;
         return (x != null) ? x.name : i.inner.name;
     }

If you can't test for specific types then you can use reflection to test for the name property itself:

i => {
         var pi = i.GetType().GetProperty("name");
         return (pi != null) ? pi.GetValue(i, null) : i.inner.name;
     }
Sign up to request clarification or add additional context in comments.

4 Comments

Don't you need to cast i to TypeThatHasNameProperty before you can access the Name property?
@dtb: Probably, I suppose it depends on what the rest of the OP's code looks like. (But it wouldn't do any harm to make the cast anyway, although in my example code I think using as is probably more appropriate than a plain cast.)
great job on this answer
This is a more appropriate answer
7

Yes, the conditional operator ("ternary operator") does what you want:

(i => i.name != null ? i.name : i.inner.name)

Assuming, of course, that you can detect the "existence" of the name by checking for null.

Edit: In that case, Kirschstein's answer is better, of course.

1 Comment

What I meant is, i.name doesn't exist at all. The property name isn't there. I can't use null. Apologies if I made that unclear.
4

Why don't you give each object a ToDictionary method of their own, as they obviously have their own behaviours in this case.

If you can't add to the objects, because you don't own them, you can always write extension methods for them.

Any reason your trying to force feed them into one "common" function?

2 Comments

Maybe overriding ToString() would be the best behavioural choice for these objects. Of course, that depends on whether you rely on other behaviour in ToString() elsewhere...
@Sekhat I was just seeing if I could combine it into one function as I need to do it quite a few times. For the sake of tidiness.
0

something along the lines of

collection1.ForEach(i => myDictionary.Add((i.name.length == 0 ? i.inner.name : i.name),value);

(untested) should do the trick if i.name is not null (an empty string), or

collection1.ForEach(i => myDictionary.Add((i.name ?? i.inner.name),value);

(also untested)

Comments

-1

as an inline if query I would use a ternary operator, so:

(i.name != null ? set id to i.name : set id to i.inner.name)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.