classe dumper objet
Je cherche une classe qui peut afficher un objet et toutes ses valeurs de feuille dans un format similaire à ceci:
User
- Name: Gordon
- Age : 60
- WorkAddress
- Street: 10 Downing Street
- Town: London
- Country: UK
- HomeAddresses[0]
...
- HomeAddresses[1]
...
(ou un format plus clair). Cela serait équivalent à:
public class User
{
public string Name { get;set; }
public int Age { get;set; }
public Address WorkAddress { get;set; }
public List<Address> HomeAddresses { get;set; }
}
public class Address
{
public string Street { get;set; }
public string Town { get;set; }
public string Country { get;set; }
}
Une sorte de représentation de chaîne du contrôle PropertyGrid, moins avoir à implémenter un grand ensemble de concepteurs pour chaque type.
PHP a quelque chose qui fait cela appelé var_dump . Je ne veux pas utiliser une montre, car c'est pour l'impression.
Quelqu'un Pourrait-il m'indiquer quelque chose comme cela, s'il existe? Ou, écrivez-en un pour une prime.
11 réponses
Le dumper objet posté dans le lien de sgmoore:
//Copyright (C) Microsoft Corporation. All rights reserved.
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
// See the ReadMe.html for additional information
public class ObjectDumper {
public static void Write(object element)
{
Write(element, 0);
}
public static void Write(object element, int depth)
{
Write(element, depth, Console.Out);
}
public static void Write(object element, int depth, TextWriter log)
{
ObjectDumper dumper = new ObjectDumper(depth);
dumper.writer = log;
dumper.WriteObject(null, element);
}
TextWriter writer;
int pos;
int level;
int depth;
private ObjectDumper(int depth)
{
this.depth = depth;
}
private void Write(string s)
{
if (s != null) {
writer.Write(s);
pos += s.Length;
}
}
private void WriteIndent()
{
for (int i = 0; i < level; i++) writer.Write(" ");
}
private void WriteLine()
{
writer.WriteLine();
pos = 0;
}
private void WriteTab()
{
Write(" ");
while (pos % 8 != 0) Write(" ");
}
private void WriteObject(string prefix, object element)
{
if (element == null || element is ValueType || element is string) {
WriteIndent();
Write(prefix);
WriteValue(element);
WriteLine();
}
else {
IEnumerable enumerableElement = element as IEnumerable;
if (enumerableElement != null) {
foreach (object item in enumerableElement) {
if (item is IEnumerable && !(item is string)) {
WriteIndent();
Write(prefix);
Write("...");
WriteLine();
if (level < depth) {
level++;
WriteObject(prefix, item);
level--;
}
}
else {
WriteObject(prefix, item);
}
}
}
else {
MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
WriteIndent();
Write(prefix);
bool propWritten = false;
foreach (MemberInfo m in members) {
FieldInfo f = m as FieldInfo;
PropertyInfo p = m as PropertyInfo;
if (f != null || p != null) {
if (propWritten) {
WriteTab();
}
else {
propWritten = true;
}
Write(m.Name);
Write("=");
Type t = f != null ? f.FieldType : p.PropertyType;
if (t.IsValueType || t == typeof(string)) {
WriteValue(f != null ? f.GetValue(element) : p.GetValue(element, null));
}
else {
if (typeof(IEnumerable).IsAssignableFrom(t)) {
Write("...");
}
else {
Write("{ }");
}
}
}
}
if (propWritten) WriteLine();
if (level < depth) {
foreach (MemberInfo m in members) {
FieldInfo f = m as FieldInfo;
PropertyInfo p = m as PropertyInfo;
if (f != null || p != null) {
Type t = f != null ? f.FieldType : p.PropertyType;
if (!(t.IsValueType || t == typeof(string))) {
object value = f != null ? f.GetValue(element) : p.GetValue(element, null);
if (value != null) {
level++;
WriteObject(m.Name + ": ", value);
level--;
}
}
}
}
}
}
}
}
private void WriteValue(object o)
{
if (o == null) {
Write("null");
}
else if (o is DateTime) {
Write(((DateTime)o).ToShortDateString());
}
else if (o is ValueType || o is string) {
Write(o.ToString());
}
else if (o is IEnumerable) {
Write("...");
}
else {
Write("{ }");
}
}
}
Mise à jour 2015
YAML sert également très bien cet objectif, c'est ainsi que cela peut être fait avec YamlDotNet
install-package YamlDotNet
private static void DumpAsYaml(object o)
{
var stringBuilder = new StringBuilder();
var serializer = new Serializer();
serializer.Serialize(new IndentedTextWriter(new StringWriter(stringBuilder)), o);
Console.WriteLine(stringBuilder);
}
Vous pouvez utiliser le sérialiseur JSON, qui devrait être facile à lire pour quiconque utilise JSON
User theUser = new User();
theUser.Name = "Joe";
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(myPerson.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, theUser );
string json = Encoding.Default.GetString(ms.ToArray());
Vous pouvez trouver le projet ObjectDumper sur CodePlex. Vous pouvez également l'ajouter via Visual Studio 2010 NuGet package manager.
Si vous travaillez avec le balisage, System.Web.ObjectInfo.Print
(ASP.NET les Pages web 2 ) accompliront cela, bien formaté pour HTML.
Par exemple:
@ObjectInfo.Print(new {
Foo = "Hello",
Bar = "World",
Qux = new {
Number = 42,
},
})
Dans une page web, produit:
Voici une extension visual studio que j'ai écrite pour faire ceci:
Https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f
En action:
Vous pourriez écrire très facilement avec un peu de réflexion. Quelque chose comme:
public void Print(object value, int depth)
{
foreach(var property in value.GetType().GetProperties())
{
var subValue = property.GetValue(value);
if(subValue is IEnumerable)
{
PrintArray(property, (IEnumerable)subValue);
}
else
{
PrintProperty(property, subValue);
}
}
}
Vous pouvez écrire les méthodes PrintArray et PrintProperty.
J'ai une méthode d'Extension handy T. Dump () qui devrait être assez proche des résultats que vous recherchez. Comme c'est une méthode d'extension, c'est non invasif et devrait fonctionner sur tous les objets POCO.
Exemple D'Utilisation De
var model = new TestModel();
Console.WriteLine(model.Dump());
Exemple De Sortie
{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: [],
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}
Je sais que c'est une vieille question, mais je pensais jeter une alternative qui a fonctionné pour moi, m'a pris environ deux minutes à faire.
Installer Newtonsoft Json.NET: http://james.newtonking.com/json
(ou version nuget) http://www.nuget.org/packages/newtonsoft.json/
Assemblage De Référence:
using Newtonsoft.Json;
Vider la chaîne JSON dans le journal:
txtResult.Text = JsonConvert.SerializeObject(testObj);
Si vous n'avez pas envie de copier et coller le code de Chris S, Les échantillons Visual Studio 2008 sont livrés avec un ObjectDumper.
Lecteur: \ Program Files \ Microsoft Visual Studio 9.0 \ Samples \ 1033\LinqSamples\ObjectDumper
Voici une alternative:
using System.Reflection;
public void Print(object value)
{
PropertyInfo[] myPropertyInfo;
string temp="Properties of "+value+" are:\n";
myPropertyInfo = value.GetType().GetProperties();
for (int i = 0; i < myPropertyInfo.Length; i++)
{
temp+=myPropertyInfo[i].ToString().PadRight(50)+" = "+myPropertyInfo[i].GetValue(value, null)+"\n";
}
MessageBox.Show(temp);
}
(juste toucher le niveau 1, Pas de profondeur, mais en dit long)
Pour la plupart des classes, vous pouvez utiliser le DataContractSerializer