2017-11-09 4 views
5

So stieß ich auf die folgenden:Implizite Umwandlung in String/String in interpoliert String

Console.WriteLine(currentRow["Projekt"]); 
Console.WriteLine($"{currentRow["Projekt"]}"); 
Console.WriteLine($"{(string)currentRow["Projekt"]}"); 

Mit der Ausgabe:

> Data that i want 
> Namespace.ExcelDataField 
> Data that i want 

Wo ExcelDataField i offensichtlich eine Klasse schrieb ich mir Daten zu helfen, lesen aus einem Excel-Blatt. Ich habe versucht, dies zu implementieren, um VBAs DAO-Zugriff mit MoveFirst/Next zu ähneln und immer 1 Zeile von Daten (currentRow) verfügbar zu machen.

Ich habe eine Klasse ExcelDataField verwendet, um die Daten, die aus meiner Excel-Tabelle kommen, zu kapseln, da die Daten als Dynmic aus der Excel-Tabelle kommen.

public class ExcelDataField<T> 
{ 
    private Excel.Range m_XlRange; 
    private int m_Row; 
    private int m_Col; 

    public T Data 
    { 
     get 
     { 
      return (T)(this.m_XlRange.Cells[this.m_Row, this.m_Col] as Excel.Range)?.Value2; 
     } 

     set 
     { 
      this.m_XlRange.Cells[this.m_Row, this.m_Col] = value; 
     } 
    } 

    public ExcelDataField(Excel.Range range, int row, int col) 
    { 
     this.m_XlRange = range; 
     this.m_Row = row; 
     this.m_Col = col; 
    } 

    public static implicit operator T(ExcelDataField<T> dataField) 
    { 
     return dataField.Data; 
    } 
} 

Zeit für Testzwecke Ich asuming, dass alle Daten später leicht als String behandelt werden können, um ich eine Überlastung dieser Klasse ExcelDataField : ExcelDataField<string> gemacht, die die Klasse I ein Excel-Blatt in und einfach zu lesen, bin mit Lesen es zurück zur Konsole.

Alles funktioniert gut, solange ich keine interpolierten Strings verwende, die offensichtlich meine implizite Konvertierung nicht finden. Ich habe versucht, ExcelDataField : ExcelDataField<string> zu ExcelDataField : ExcelDataField<String> zu ändern, aber beide funktionieren nicht.

In meinem Verständnis interpolierte Strings verwenden den FormattableString-Typ, der keine implizite Konvertierung von String oder String nur explizit hat.

Meine Frage wäre, kann jemand genauer erklären, was genau hier vor sich geht und gibt es einen sauberen Weg für mich, interpolierte Strings zu verwenden?

Antwort

3

Interpolated Saiten werden entweder in einen string.Format(...) Ausdruck kompiliert werden, oder in eine Wrapper-Klasse kompiliert FormattableString die string.Format(...)

Hier ist ein Überblick über die Optionen verwendet intern betrachtet für jeden dieser Parameter:

  1. Hat das eine ICustomFormatter-string.Format(...) Rückkehr gegeben IFormatProvider, wenn Sie gefragt? Wenn ja, konsultieren Sie zuerst ICustomFormatter.Format für jeden Wert.
  2. Implementiert der Typ des Parameterwerts IFormattable? Wenn ja, dann IFormattable.ToString
  3. genannt Wenn nein, dann die .ToString() Methode direkt auf dem Wert

Also in Ihrem Fall aufgerufen wird, die beste Wahl ist wahrscheinlich nur ToString() außer Kraft setzen.

Der genaue Code (mindestens in Referenzquelle) ist innerhalb StringBuilder, gefunden here: StringBuilder.cs, line 1441 - AppendFormatHelper method.

4

Es ist ziemlich einfach. $"{currentRow["Projekt"]}" ist genau das gleiche wie string.Format("{0}", currentRow["Projekt"]). Auf der object Instanz, die von currentRow["Projekt"] bereitgestellt wird, wird die ToString Methode aufgerufen. Die Standardimplementierung unter object ist, dass sie den Typnamen zurückgibt.

Also im Grunde alles, was Sie tun müssen, ist dieses Verhalten zu überschreiben. Sie können durch Überschreiben der ToString Methode tun:

public override string ToString() 
{ 
    return dataField.Data?.ToString(); 
} 
Verwandte Themen