所以我偶然发现了以下内容:
Console.WriteLine(currentRow["Projekt"]);
Console.WriteLine($"{currentRow["Projekt"]}");
Console.WriteLine($"{(string)currentRow["Projekt"]}");
输出:
> Data that i want
> Namespace.ExcelDataField
> Data that i want
ExcelDataField显然是我写的一个类,用来帮助我从excel表中读取数据。我尝试将其实现为类似于使用MoveFirst / Next的VBA DAO访问,并且总是暴露1行数据(currentRow)。
我使用ExcelDataField类来封装来自excel表格的数据,因为数据来自excel表格中的动态。
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;
}
}
目前我正在考虑测试目的,以后所有数据都可以轻松地作为字符串处理,因此我对这个类ExcelDataField : ExcelDataField<string>
进行了重载,这是我用来读取excel表的类,只是阅读它回到控制台。
只要我没有使用内插字符串显然无法找到我的隐式转换,一切正常。我试图更改ExcelDataField : ExcelDataField<string
&gt;至ExcelDataField : ExcelDataField<String>
,但两人都无法工作。
在我的理解中,插值字符串使用FormattableString类型,该类型不具有来自字符串或字符串的任何隐式转换仅显式。
我的问题是,任何人都可以更详细地解释这里究竟发生了什么,是否有一种干净的方式让我能够使用插值字符串?
答案 0 :(得分:5)
这很容易。 $"{currentRow["Projekt"]}"
与string.Format("{0}", currentRow["Projekt"])
相同。在object
提供的currentRow["Projekt"]
实例上,调用了ToString
方法。 object
上的默认实现是返回类型名称。
所以你基本上所要做的就是覆盖那种行为。您可以通过覆盖ToString
方法来实现:
public override string ToString()
{
return dataField.Data?.ToString();
}
答案 1 :(得分:3)
插值字符串将被编译为string.Format(...)
表达式,或编译为内部使用string.Format(...)
的包装类FormattableString
以下是对每个此类参数考虑的选项的概述:
IFormatProvider
的{{1}}在被问到时会返回string.Format(...)
吗?如果是,请先咨询ICustomFormatter
每个值。ICustomFormatter.Format
?如果是,则调用IFormattable.ToString IFormattable
方法
醇>
因此,在您的情况下,您最好的选择可能只是覆盖.ToString()
。
确切代码(至少在参考来源中)位于ToString()
内,找到here: StringBuilder.cs, line 1441 - AppendFormatHelper method。