1

There is a function I want to implement in C#:

public string getName(object ob)
{
    // TODO: if object has "Name" attribute, return "Name".Value, else return null;
}

When I invoke this function,

string result1 = getName(new {Name = "jack", Age = 12})     // result1 = "jack"
string result2 = getName(new {Age = 12})      // result2 = null

I know it's easy to implement in JavaScript or other dynamic languages... I am curious about if it can implement in C#?

3
  • 1
    Did you try it out if yes what was the output? Commented Jun 22, 2018 at 5:55
  • What is the expected result for getName(new {Name = new MyCustomObject()})? Commented Jun 22, 2018 at 6:02
  • @grek40 I didn't consider it... But the answer is enough for me now. I just want to know if can implement it... Commented Jun 22, 2018 at 6:09

3 Answers 3

5

Yes, you can. Take a look to Reflection

public string getName(object ob)
{
    var type = ob.GetType();
    if (type.GetProperty("Name") == null) return null;
    else return type.GetProperty("Name").GetValue(ob, null);
}
Sign up to request clarification or add additional context in comments.

Comments

2

There is several ways to achieve that. For example by using reflection. It will take one line code:

public static string GetName(object ob) =>
    ob.GetType().GetProperty("Name")?.GetValue(ob)?.ToString();

Or below c#6 way:

public static string GetName(object ob)
{
    return ob.GetType().GetProperty("Name")?.GetValue(ob)?.ToString();
}

You can even serialize your object to JSON or XML, then try to get your value from that:

public static string GetName(object obj)
{
    string json = JsonConvert.SerializeObject(obj);
    string result = JsonConvert.DeserializeAnonymousType(json, new { Name = "" })?.Name;
    return result;
}

Comments

1

UPDATE: While this may work for your needs, it is probably not the best solution as pointed out by Grek40, and Damien_The_Unbeliever in comments below due to several limitations. Not completely deleting the answer as it may give you some information about the alternative despite of its limitations.

Original Answer:

Try this.. Rextester can be found -- http://rextester.com/DQOBW76322

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {

            string result1 = getName(new {Name = "jack", Age = 12});    // result1 = "jack"
            string result2 = getName(new {Age = 12});

            Console.WriteLine(result1);
            Console.WriteLine(result2);
        }

        public static string getName(object obj)
        {
            var testData = obj.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(obj).ToString());

            if(testData.Any(d => d.Key == "Name")){
                return testData["Name"];
            }

            return null;
        }
    }
}

4 Comments

Isn't it a bit of overkill to first invoke all property getters before deciding which to use?
@grek40, just realized it. Could potentially be made much simpler (or efficient rather, will update the answer soon.)
And it'll throw if the class has any set-only properties (which, yes, I know, are evil, but can exist)
@Damien_The_Unbeliever Didn't think of that either, just updated the answer about this limitation. Thanks for pointing this out.

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.