Click here to Skip to main content
14,982,875 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi,

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:

C#
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 JSON.net 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"}}
vs.
input2: {"cInfo":{"myName":{"value":""}}}

C#
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; // 
}
Posted
Updated 14-May-13 10:34am
v2
Comments
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;}
[AliasAttribute("myName")]
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... :-)
—SA
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... :-)

—SA
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.

I ended up doing something like:

C#
public dynamic myName { get; set; }

if (myName != null)
  if (myName is string)
     // can access it directly
  else
    // 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?)
   
Might not be the most elegant one, but it is a working solution:

C#
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);
        }
    }
}
   
Comments
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:
http://msdn.microsoft.com/en-us/library/ms733127.aspx[^].

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:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx[^].

Don't you think your problem is already solved?

—SA
   
v3

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