Click here to Skip to main content
15,890,336 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

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);
        }
    }
}
 
Share this answer
 
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
 
Share this answer
 
v3
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?)
 
Share this answer
 

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