So I stumbled upon the following:
Console.WriteLine(currentRow["Projekt"]);
Console.WriteLine($"{currentRow["Projekt"]}");
Console.WriteLine($"{(string)currentRow["Projekt"]}");
With the output:
> Data that i want
> Namespace.ExcelDataField
> Data that i want
Where ExcelDataField is obviously a class I wrote to help me read data out of an excel sheet. I tried to implement this to resemble VBAs DAO access with MoveFirst/Next and always expose 1 row of data (currentRow).
I used a class ExcelDataField to encapsulate the data coming out of my excel sheet because the type will be dynamic
when reading.
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;
}
}
Currently I am assuming for testing purposes that all data can later easily be handled as a string so I made an overload of this class ExcelDataField : ExcelDataField<string>
which is the class I am using to read an excel sheet into. in the example, I am just reading it back to console.
Everything works fine as long as I am not using interpolated strings which obviously don't find my implicit conversion. I tried to change ExcelDataField : ExcelDataField<string
> to ExcelDataField : ExcelDataField<String>
but both don't work.
In my understanding interpolated strings use the FormattableString type which doesn't have any implicit conversion from string or String only explicit.
My question would be can anyone explain in greater detail what exactly is going on here and is there a clean way for me to able to use interpolated strings?
It is fairly easy. $"{currentRow["Projekt"]}"
is just the same as string.Format("{0}", currentRow["Projekt"])
. On the object
instance provided by currentRow["Projekt"]
, the ToString
method is called. The default implementation on object
is that it returns the type name.
So basically all you have to do is to override that behavior. You can do that by overriding the ToString
method:
public override string ToString()
{
return dataField.Data?.ToString();
}
Interpolated strings will either be compiled into a string.Format(...)
expression, or compiled into a wrapper class FormattableString that internally uses string.Format(...)
Here's a rundown of the options considered for each such parameter:
IFormatProvider
given to string.Format(...)
return a ICustomFormatter
when asked? If yes then consult ICustomFormatter.Format
for each value first.IFormattable
? If yes, then IFormattable.ToString is called.ToString()
method is called directly on the valueSo in your case, your best option is probably to just override ToString()
.
The exact code (at least in reference source) is inside StringBuilder
, found here: StringBuilder.cs, line 1441 - AppendFormatHelper method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With