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