2012-11-04 11 views
7
 var sample = new 
     { 
      Time = DateTime.Now, 
      Name = "Hello" 
     }; 
     Trace.TraceInformation("{0}", sample); 

uscite comeOverride ToString() l'attuazione di anonimi oggetti

ProcessInvocation86.exe Informazioni: 0: {Tempo = 04.11.2012 22:07:52, Name = Ciao}

Mi piacerebbe una diversa formattazione nella mia applicazione. C'è un modo per cambiare l'implementazione di ToString() per oggetti anonimi in C#? Forse qualche campo statico per AppDomain o qualcosa del genere?

+1

Probabilmente non per i tipi anonimi. Quando inizi a passare da una semplice struttura dati a un oggetto un po 'più ricco che espone funzionalità (come l'override di un metodo), dovrai definire un tipo esplicito. – David

+1

Sono riuscito a farlo: 'var sample = new {Time = DateTime.Now, Name =" Hello ", ToString = new Func (() => {return" xxx ";})}; Console.WriteLine (" {0} ", sample.ToString());'. Sfortunatamente sembra che non ci sia modo di accedere a 'this' da ToString Func, in modo che possa restituire solo costanti o variabili globali - inutile suppongo :( – Ondra

risposta

8

No, non è possibile farlo - ToString, Equals e GetHashCode hanno un'implementazione predefinita fornita dal framework. Per sovrascrivere questa funzionalità devi ereditare dal tuo tipo anonimo, il che è impossibile.

Utilizzare String.Format per ottenere l'output desiderato.

+3

Aggiungerò che se hai bisogno di questo tipo di funzionalità, dovresti definire un classe reale ed estenderlo di conseguenza. –

+0

@JonathonReinhart sì, stavo solo scrivendo questo aggiornamento! –

4

Per quanto ne so, non c'è modo di ignorare il comportamento predefinito ToString.
potrebbe essere utile guardare alcuni dei messaggi di Eric Lippert su tipi anonimi: http://blogs.msdn.com/b/ericlippert/archive/tags/anonymous+types/

Probabilmente la cosa migliore per creare una semplice classe per questo scopo:

esempio

public class MyClass 
{ 
    public DateTime Time { get; set; } 
    public string Name { get; set; } 

    public override string ToString() 
    { 
    return string.Format("Time = {0}. Name = {1}.", Time, Name); 
    } 
} 
1

Lo so, alcuni ragazzi saranno in realtà mi pugno per una soluzione del genere e sono d'accordo, che non si dovrebbe usare in produzione. Se si dispone di funzionalità specifiche per alcuni dati, questo dovrebbe sicuramente andare alla classe separata. Ma per problemi minori, è possibile utilizzare un po 'di riflessione come questo per scrivere qualche formattazione personalizzata (ripeto, non sto suggerendo di utilizzarlo in produzione):

private string FormatProperties<T> (T obj) 
{ 
    string result = ""; 
    var type = typeof(T); 
    foreach (var prop in type.GetProperties()) 
    { 
     result += string.Format("{0}:{1}\r\n", prop.Name, prop.GetValue(obj)); 
    } 
    return result; 
} 

Poi la chiamata

var anon = new {Name = "Ilya", Surname = "Ivanov"}; 
Console.WriteLine (FormatProperties(anon)); 

si tradurrà in stampato

Name:Ilya 
Surname:Ivanov 

e quindi è possibile memorizzare nella cache i tipi di vantaggi di prestazioni e di entrare in un altro tipo di problemi.

0

questo non è esattamente l'ideale .. ma è possibile creare un metodo di estensione che accetta una funzione che esegue la formattazione.

Seguendo l'esempio formattato per LINQPad ESEMPIO

void Main() 
{ 
var sample = new 
     { 
      Time = DateTime.Now, 
      Name = "Hello", 
     }; 

    sample.ToAnonString(()=>sample.Name).Dump(); 

} 
public static class ovs{ 
     public static string ToAnonString(this object o,Func<string> exp){ 
     return exp(); 
     } 
    }