Implicit conversion to string / string inside interpolated string

So, I came across the following:

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

With an exit:

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

Where is ExcelDataField, I obviously have a class that I wrote to help me read data from an excel sheet. I tried to implement this so that it matches the DAO VBA access using MoveFirst / Next and always set 1 row of data (currentRow).

I used the ExcelDataField class to encapsulate data coming out of my excel sheet, because the data comes in as dynamic from an excel sheet.

 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; } } 

I'm currently going for testing purposes that all data can be easily processed as a string, so that I do an overload of this ExcelDataField : ExcelDataField<string> class ExcelDataField : ExcelDataField<string> , which is the class that I use to read the Excel worksheet and just read it back to comfort .

Everything works fine until I use interpolated strings which obviously don't find my implicit conversion. I tried changing ExcelDataField : ExcelDataField<string > to ExcelDataField : ExcelDataField<string> , but both of them do not work.

In my understanding, interpolated strings use the FormattableString type, which has no implicit conversion from string or string only explicit.

My question could someone explain in more detail what exactly is happening here, and is there a clean way for me to use interpolated strings?

+5
source share
2 answers

Interpolated strings will either be compiled into a string.Format(...) expression or compiled into a FormattableString wrapper class that internally uses string.Format(...)

Here is a description of the options considered for each such parameter:

  • Does IFormatProvider string.Format(...) a ICustomFormatter on request? If so, first consult ICustomFormatter.Format for each value.
  • Is the value type of the IFormattable parameter IFormattable ? If so, then IFormattable.ToString is called
  • If not, the .ToString() method is called directly above the value

So, in your case, the best option is to simply override ToString() .

The exact code (at least in the source) is inside StringBuilder , found here: StringBuilder.cs, line 1441 - AppendFormatHelper method .

+3
source

This is pretty easy. $"{currentRow["Projekt"]}" matches string.Format("{0}", currentRow["Projekt"]) . In the object instance provided by currentRow["Projekt"] , the ToString method is called. The default implementation on object is that it returns a type name.

So basically all you have to do is override this behavior. You can do this by overriding the ToString method:

 public override string ToString() { return dataField.Data?.ToString(); } 
+4
source

Source: https://habr.com/ru/post/1273241/


All Articles