2016-10-13 10 views
1

:재정 ToString 나는 다음과 같은 코드가 메인에서

var json = new JValue { Object = new Dictionary<string, JValue>() }; 
json["name"] = new JValue("Lebron James"); 
json["age"] = new JValue(23); 

if (json.Type == JType.Object) 
{ 
    foreach (var value in json.Object) 
    { 
     System.Console.WriteLine(value.ToString()); 
    } 
} 

사용자 정의 클래스 및 데이터 유형 것은 다음과 같다 : 나는 toString를 오버라이드 (override) 해, 시도했습니다

public enum JType 
{ 
    Null, 
    Bool, 
    Number, 
    String, 
    Array, 
    Object, 
} 

public class JValue 
{ 
    public JType Type { get; private set; } 
    private JsonValue Value { get; set; } 

    public JValue() 
    { 
     Type = JType.Null; 
    } 

    public JValue(bool value) 
    { 
     Type = JType.Bool; 
     Value = new JsonBool { Value = value }; 
    } 

    public JValue(double value) 
    { 
     Type = JType.Number; 
     Value = new JsonNumber { Value = value }; 
    } 

    public JValue(string value) 
    { 
     Type = JType.String; 
     Value = new JsonString { Value = value }; 
    } 

    public JValue(List<JValue> values) 
    { 
     Type = JType.Array; 
     Value = new JsonArray { Values = values }; 
    } 

    public JValue(Dictionary<string, JValue> values) 
    { 
     Type = JType.Object; 
     Value = new JsonObject { Values = values }; 
    } 

    public bool Null 
    { 
     get { return Type == JType.Null; } 
     set { Type = JType.Null; Value = null; } 
    } 

    public bool Bool 
    { 
     get 
     { 
      if (Type != JType.Bool) throw new InvalidCastException(); 
      return ((JsonBool)Value).Value; 
     } 
     set 
     { 
      Type = JType.Bool; 
      Value = new JsonBool { Value = value }; 
     } 
    } 

    public double Number 
    { 
     get 
     { 
      if (Type != JType.Number) throw new InvalidCastException(); 
      return ((JsonNumber)Value).Value; 
     } 
     set 
     { 
      Type = JType.Number; 
      Value = new JsonNumber { Value = value }; 
     } 
    } 

    public string String 
    { 
     get 
     { 
      if (Type != JType.String) throw new InvalidCastException(); 
      return ((JsonString)Value).Value; 
     } 
    } 

    public List<JValue> Array 
    { 
     get 
     { 
      if (Type != JType.Array) throw new InvalidCastException(); 
      return ((JsonArray)Value).Values; 
     } 
     set 
     { 
      Type = JType.Array; 
      Value = new JsonArray { Values = value }; 
     } 
    } 

    public Dictionary<string, JValue> Object 
    { 
     get 
     { 
      if (Type != JType.Object) throw new InvalidCastException(); 
      return ((JsonObject)Value).Values; 
     } 
     set 
     { 
      Type = JType.Object; 
      Value = new JsonObject { Values = value }; 
     } 
    } 

    public JValue this[string key] 
    { 
     get { return Object[key]; } 
     set { Object[key] = value; } 
    } 

    public int Count 
    { 
     get { return Array.Count; } 
    } 

    public JValue this[int index] 
    { 
     get { return Array[index]; } 
     set { Array[index] = value; } 
    } 

    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

internal class JsonValue 
{ 
} 

internal class JsonBool : JsonValue 
{ 
    public bool Value; 
    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

internal class JsonNumber : JsonValue 
{ 
    public double Value; 
    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

internal class JsonString : JsonValue 
{ 
    public string Value; 
    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

internal class JsonArray : JsonValue 
{ 
    public List<JValue> Values; 
} 

internal class JsonObject : JsonValue 
{ 
    public Dictionary<string, JValue> Values; 
} 

을 ()이 함수와 함께하지만 그것은 내게 가치를주지 않습니다.

public override string ToString() 
{ 
    return Value.ToString(); 
} 

어떤 조언을 주시면 감사하겠습니다.

+0

보고 싶은 출력은 무엇입니까? –

+0

값 자체를 출력하려고합니다. – Tommizzy

답변

2

당신은 JValue.ToString()이 클래스의 전체 이름을 표시 할 수 있도록 오버라이드 (override)하지 않는 JsonValue.ToString() 메소드를 호출하기 때문에 JsonValue에서 파생 된 각 클래스의 ToString() 메서드를 재정의해야합니다.

또한 public 필드를 public auto-properties로 바꾸는 것이 좋습니다. 그래서 예를 들면

:

internal class JsonBool : JsonValue 
{ 
    public bool Value { get; set; } 

    public string override ToString() 
    { 
     return Value.ToString(); 
    } 
} 

업데이트 # 1 :

당신이 ToString() 재정의 톤을 피할 수 있도록 더 나은 솔루션은 제네릭 형식을 소개하는 것입니다.

internal class JsonValue<T> 
{ 
    public T Value { get; set; } 

    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

internal class JsonBool : JsonValue<bool> 
{ 
} 

internal class JsonDouble : JsonValue<double> 
{ 
} 
+0

다음과 같이 문자열을 초기화하면 작동합니다. – Tommizzy

+0

다음과 같이 문자열을 초기화하면 작동합니다. var person = new JValue ("Lebron"); – Tommizzy

+0

사전 및 배열의 ​​값을 표시하려고하면 다음과 같은 내용이 표시됩니다. System.Collections.Generic.Dictionary'2 [System.String, oop_hw.JValue]. 사전 및 배열 클래스의 각 루프에 대해 필요하다고 가정하고 있지만이를 구성하는 방법을 잘 모르겠습니다. – Tommizzy

0

가보의 대답은 당신이 JsonValue 파생 개체에 ToString를 오버라이드 (override) 할 필요가 정확하다. 제네릭에 대한 그의 다른 충고와 필드를 특성으로 대체하는 것도 좋습니다.

배열 및 객체 유형의 경우 해당 유형에 포함 된 값을 반복해야합니다. 출력을 원하는대로 나오게하려면 코드를 가지고 놀아야 할 수도 있습니다.

아래 코드는 중첩 된 항목을 고려하지 않음에 유의하십시오. 예를 들어 JsonObjectJValue 인 경우 이고JsonObject이고 더 많은 값을 보유하고 있습니다.

internal class JsonArray : JsonValue 
{ 
    public List<JValue> Values; 
    public override string ToString() 
    { 
     return string.Join(", ", Values ?? Enumerable.Empty<JValue>()); 
    } 
} 

internal class JsonObject : JsonValue 
{ 
    public Dictionary<string, JValue> Values; 
    public override string ToString() 
    { 
     if (Values == null || Values.Count <= 0) 
     { 
      return ""; 
     } 

     var builder = new StringBuilder(); 
     foreach (var item in Values) 
     { 
      builder 
       .AppendFormat("{0}: {1}", item.Key, item.Value) 
       .AppendLine(); 
     } 

     return builder.ToString(); 
    } 
}