【问题标题】:Implicit conversion to String/string inside interpolated string内插字符串内隐式转换为字符串/字符串
【发布时间】:2017-11-09 13:08:07
【问题描述】:

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

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 表的数据,因为读取时类型将为 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;
    }
}

目前,出于测试目的,我假设所有数据以后都可以轻松地作为字符串处理,因此我对此类 ExcelDataField : ExcelDataField&lt;string&gt; 进行了重载,这是我用来读取 Excel 工作表的类。在示例中,我只是将其读回控制台。

只要我不使用显然找不到我的隐式转换的插值字符串,一切都可以正常工作。我尝试将ExcelDataField : ExcelDataField&lt;string> 更改为ExcelDataField : ExcelDataField&lt;String&gt;,但都不起作用。

据我了解,插值字符串使用 FormattableString 类型,它没有从字符串进行任何隐式转换或仅显式地转换字符串。

我的问题是谁能更详细地解释这里到底发生了什么?有没有一种干净的方法让我能够使用插值字符串?

【问题讨论】:

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


    【解决方案1】:

    这相当容易。 $"{currentRow["Projekt"]}"string.Format("{0}", currentRow["Projekt"]) 相同。在currentRow["Projekt"] 提供的object 实例上,调用了ToString 方法。 object 的默认实现是返回类型名称。

    所以基本上你所要做的就是覆盖那个行为。您可以通过覆盖 ToString 方法来做到这一点:

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

    【讨论】:

      【解决方案2】:

      内插字符串要么编译成string.Format(...)表达式,要么编译成内部使用string.Format(...)的包装类FormattableString

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

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

      所以在你的情况下,你最好的选择可能是覆盖ToString()

      确切的代码(至少在参考源中)在StringBuilder 中,在here: StringBuilder.cs, line 1441 - AppendFormatHelper method 中找到。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-21
        • 1970-01-01
        • 2019-01-05
        • 2010-10-17
        • 2019-10-10
        • 2019-04-01
        相关资源
        最近更新 更多