c# - clase de volcado de objetos
object-dumper (11)
Aquí hay una alternativa:
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);
}
(solo toca el nivel 1, sin profundidad, pero dice mucho)
Estoy buscando una clase que pueda mostrar un objeto y todos sus valores de hoja en un formato similar a este:
User
- Name: Gordon
- Age : 60
- WorkAddress
- Street: 10 Downing Street
- Town: London
- Country: UK
- HomeAddresses[0]
...
- HomeAddresses[1]
...
(O un formato más claro). Esto sería equivalente a:
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; }
}
Un tipo de representación de cadena del control PropertyGrid, menos tener que implementar un gran conjunto de diseñadores para cada tipo.
PHP tiene algo que hace esto llamado var_dump . No quiero usar un reloj, ya que es para imprimirlo.
¿Podría alguien señalarme algo así si existe? O bien, escribe uno para una recompensa.
Aquí hay una extensión de estudio visual que escribí para hacer esto:
https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f
en acción:
El volcador de objetos publicado en el enlace 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("{ }");
}
}
}
Actualización 2015
YAML también sirve para este propósito bastante bien, así es como se puede hacer con 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);
}
Para la mayoría de las clases, puede usar DataContractSerializer
Podría usar el serializador JSON, que debería ser fácil de leer para cualquier persona que trabaje con 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());
Podrías escribir eso muy fácilmente con un poco de reflexión. Algo así como:
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);
}
}
}
Puede escribir los métodos PrintArray y PrintProperty.
Puede encontrar el proyecto ObjectDumper en CodePlex. También puede agregarlo a través del administrador de paquetes Nuget de Visual Studio 2010.
Sé que esta es una vieja pregunta, pero pensé que arrojaría una alternativa que funcionara para mí, tardé unos dos minutos en hacerlo.
Instale Newtonsoft Json.NET: http://james.newtonking.com/json
(o la versión nuget) http://www.nuget.org/packages/newtonsoft.json/
Asamblea de referencia:
using Newtonsoft.Json;
Vaciar la cadena JSON para iniciar sesión:
txtResult.Text = JsonConvert.SerializeObject(testObj);
Si está trabajando con marcado, System.Web.ObjectInfo.Print
( ASP.NET Web Pages 2 ) logrará esto, muy bien formateado para HTML.
Por ejemplo:
@ObjectInfo.Print(new {
Foo = "Hello",
Bar = "World",
Qux = new {
Number = 42,
},
})
En una página web, produce:
Si no tiene ganas de copiar y pegar el código de Chris S, los ejemplos de Visual Studio 2008 vienen con un ObjectDumper.
Unidad: / Archivos de programa / Microsoft Visual Studio 9.0 / Samples / 1033 / LinqSamples / ObjectDumper
Tengo un práctico método de extensión de T.Dump () que debería estar muy cerca de los resultados que estás buscando. Como es un método de extensión, no es invasivo y debería funcionar en todos los objetos POCO.
Ejemplo de uso
var model = new TestModel();
Console.WriteLine(model.Dump());
Ejemplo de salida
{
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
}
}