在插值字符串

时间:2017-11-09 13:08:07

标签: c# excel string implicit-conversion string-interpolation

所以我偶然发现了以下内容:

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类型,该类型不具有来自字符串或字符串的任何隐式转换仅显式。

我的问题是,任何人都可以更详细地解释这里究竟发生了什么,是否有一种干净的方式让我能够使用插值字符串?

2 个答案:

答案 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

以下是对每个此类参数考虑的选项的概述:

  1. IFormatProvider的{​​{1}}在被问到时会返回string.Format(...)吗?如果是,请先咨询ICustomFormatter每个值。
  2. 参数值的类型是否实现ICustomFormatter.Format?如果是,则调用IFormattable.ToString
  3. 如果不是,则直接在值
  4. 上调用IFormattable方法

    因此,在您的情况下,您最好的选择可能只是覆盖.ToString()

    确切代码(至少在参考来源中)位于ToString()内,找到here: StringBuilder.cs, line 1441 - AppendFormatHelper method