Click here to Skip to main content
15,039,470 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:

Is it possible have a variable with the same name that can either be a string or an object that contains a string?

For example:

public mynameobj
  value: string { get; set; }

public string myName { get; set; }
public mynameobj myName { get; set; } // overload somehow, so that either works?

I tried searching a bit and I can't come up with anything.

The reason for wanting to do this is because with deserializing, the data that's being fed to me is sometimes a string and sometimes an object with a string in it. So I get an error for wrong type and I can't find a way to work around it.

An example:

input1: {"cInfo":{"myName":"some value"}}
input2: {"cInfo":{"myName":{"value":""}}}

public class info
   public string myName { get; set; }

public class myResult
  public info cInfo { get; set; }


public class someMethod()
	Newtonsoft.Json.JsonSerializerSettings jsonSettings = new Newtonsoft.Json.JsonSerializerSettings();
        jsonSettings.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
        jsonSettings.DefaultValueHandling = DefaultValueHandling.Ignore;

        myResult result = JsonConvert.DeserializeObject(json, jsonSettings);

//with input2, you get: Error reading string. Unexpected token: StartObject. Path 'cInfo.myName', line #, position #.  because it's trying to read an object as string

	string something = result.cInfo.myName; // 
Updated 14-May-13 10:34am
David_Wimbley 14-May-13 16:07pm
You could try creating a custom attribute that serves as an Alias of sorts...example

public string myName { get; set;}
public mynameobj myNameObject {get;set;}

There by having the alias tied to the property you would then be able to map the value from myNameObject in code to the myName string.
Zoltán Zörgő 14-May-13 16:08pm
Interesting... But this type alternation should not be a problem. Please provide example input, and the code you are using.
Sergey Alexandrovich Kryukov 14-May-13 16:26pm
Please see my answer. Maybe it's not so interesting as you might think... :-)
Zoltán Zörgő 14-May-13 16:28pm
Might be. I'm still curious to see a sample - it could be an third party source providing some strange json result.
Sergey Alexandrovich Kryukov 14-May-13 16:35pm
Oh, I almost forgot: JSON serialization based on Data Contract already exists. It should be very close to what OP is looking at, and very likely will be a solution.
Please see, I added new [EDIT #2] to my answer.

OP will find enough code samples... :-)

xxhatred 14-May-13 16:35pm
I added a pseudo example to the question
Zoltán Zörgő 14-May-13 16:39pm
Just at first look: why don't you use dynamic instead of exact type?
xxhatred 14-May-13 16:50pm
That somewhat helps, actually. Not sure why I didn't try that.
So replacing public string myName to public dynamic myName --
When I read it that as a string, the output is correct with input1, but with input2 I get "{ "value": "" }" because it doesn't seem that was deserialized? Or is there a way to convert that to an object also?
Zoltán Zörgő 14-May-13 17:17pm
Actually i thought about having dynamic at top level. See my answer.
Roman Zinnatov 14-May-13 16:19pm
You wrote: "sometimes a string and sometimes an object". I think, you should perform some refactoring. In other words: investigate what exactly affects on it and try to achieve that string comes by one way and object by another way.

It would be great if you could shed some light on semantics of your actions.

Might not be the most elegant one, but it is a working solution:

using System;
using Newtonsoft.Json;

namespace ConsoleApplication1
    class Program
        static void Main(string[] args)
            Newtonsoft.Json.JsonSerializerSettings jsonSettings = new Newtonsoft.Json.JsonSerializerSettings();
            jsonSettings.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
            jsonSettings.DefaultValueHandling = DefaultValueHandling.Ignore;

            dynamic result1 = JsonConvert.DeserializeObject(@"{""cInfo"":{""myName"":""some value""}}", jsonSettings);
            dynamic result2 = JsonConvert.DeserializeObject(@"{""cInfo"":{""myName"":{""value"":""another value""}}}", jsonSettings);

            Console.WriteLine("{0}\n{1}",result1.cInfo.myName, result2.cInfo.myName.value);
xxhatred 14-May-13 17:34pm
Well, this does work and I appreciate the effort. But ideally I need a way not to parse it more than once and also not have multiple sets of results.
(There is more data than in the example inputs as well, but I think it's irrelevant to the problem)
Zoltán Zörgő 14-May-13 17:57pm
Well, the better sample you give, the better solution you get. If you do it right, you don't need to parse it multiple times, and you don't get multiple result sets. And since dynamic has some performance limitations, after parsing it you can translate the result set into a list of objects of concrete type and use that one afterwards. Actually using dynamic at top level makes the work easier for the parser, and gives you the opportunity to handle the data as you need.
Makes no sense at all.

There is no such thing as "overloading", except ugly and very confusing terminology and some myths. (So many beginner have been confused! It's can be observed on CodeProject.) Methods are "overloaded" because nothing is overloaded. They are just different methods with identical names, nothing else. The calling code can compile just because in many (not all) cases a compiler can figure out which one to call by the number and types of actual parameters. And what to do with the properties of identical name and interface? How the compiler can figure out which member to use when you call (read or write) the property?

Your problem is the way you ask the question. Maybe there is a really interesting problem which may have a good solution, but good thing is sunken in your question because you are too much preoccupied with some misconception. You started to explain the purpose, and this is where you should put more effort. Explain the purpose as well as you can, in detail, then you can get a chance for much better advice.

[EDIT #1]

Actually, it looks like a very similar problem is already solved. In Data Contract. Please see:[^].

Please learn how it works, it will give you some good ideas. Learned? Now, pay attention for the Name property (named parameter) of the attribute [DataMember]. Looks somewhat familiar, isn't it?

[EDIT #2]

By the way, JSON serialization based on Data Contract is also available. Here:[^].

Don't you think your problem is already solved?

I ended up doing something like:

public dynamic myName { get; set; }

if (myName != null)
  if (myName is string)
     // can access it directly
    // is object with .value property for reading 
    // (need more checks for safety, of course)

This idea was spawned from Zoltán Zörgő, so thank you.

And also Sergey Alexandrovich for the detailed information about how it's not an 'overload'
I agree, especially with "They are just different methods with identical names, nothing else. " -- so I will start calling it that.
The DataContract info was also useful, but I wanted to find a way to do it without changing too much code, which I achieved (even if it's not ideal?)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900