【问题标题】:Will the c# compiler perform multiple implicit conversions to get from one type to another?c# 编译器会执行多次隐式转换以从一种类型转换为另一种类型吗?
【发布时间】:2009-10-23 02:12:46
【问题描述】:

假设你有一个类似下面的类:

public sealed class StringToInt { 
    private string _myString; 
    private StringToInt(string value) 
    { 
        _myString = value; 
    } public static implicit operator int(StringToInt obj) 
    { 
        return Convert.ToInt32(obj._myString); 
    } 
    public static implicit operator string(StringToInt obj) 
    { 
        return obj._myString; 
    } 
    public static implicit operator StringToInt(string obj) 
    { 
        return new StringToInt(obj); 
    } 
    public static implicit operator StringToInt(int obj) 
    { 
        return new StringToInt(obj.ToString()); 
    } 
}

然后你能写出如下代码吗:

MyClass.SomeMethodThatOnlyTakesAnInt(aString);

没有说明没有从字符串到整数的隐式转换?

[是的,我可以自己测试它,但我想我会把它放在那里,看看所有大师都怎么说]

【问题讨论】:

  • “是的,我可以自己测试它,但我想我会把它放在那里,看看所有大师都怎么说”——这是一个奇怪的句子。你做了所有努力来生成那个类,但你没有按下 F5?
  • 听起来你应该像你说的那样自己测试并发布答案,但我不是大师。
  • 我把它写在 SO 问题框中。 :D
  • 尝试复制粘贴到 Visual Studio....
  • 那里,我测试了它。你们现在都开心吗?

标签: c# casting implicit-conversion


【解决方案1】:

没有 C# 不会调用多个用户定义的隐式转换。来自 C# 规范第 6.4.3 节:

用户定义转换的评估从不涉及多个用户定义或提升的转换运算符。换句话说,从 S 类型到 T 类型的转换永远不会先执行从 S 到 X 的用户定义转换,然后再执行从 X 到 T 的用户定义转换。

【讨论】:

  • 否则你可以通过使用瞬态类型来作弊,只是为了将任何东西转换为任何东西。
  • cheat by having transient types ..like in good ol' c++.. 有时我真的很怀念
【解决方案2】:

我相当肯定这在 C# 3.0 下是不可能的。 the reference 中涵盖转换的部分是 6.4。即6.4.4“用户定义的隐式转换”。

它只讨论从 S->T(而不是 S->T->U)的转换,涵盖以下情况:

StringToInt _t = "foo";
int t = _t;

int t = (StringToInt)"foo";

这两种情况都只涉及 S->T(两次)。

我很确定这在 C# 3.0 中是不可能的。 允许 S->T->U 将需要类型匹配器执行更多工作,至少要遵循指定的算法。

【讨论】:

    【解决方案3】:

    它似乎不起作用。它至少需要一个显式转换。哦,好吧……

    【讨论】:

      【解决方案4】:

      您的 sn-p 中的错字:

      public StringToInt(string value)
      {
          _myString = value;
      }
      public static implicit operator int(StringToInt obj)
      {
          return Convert.ToInt32(obj._myString);
      }
      public static implicit operator string(StringToInt obj)
      {
          return obj._myString;
      }
      

      如果aStringStringToInt 类型,您的用法应该可以工作。

      【讨论】:

      • 是的,我抓住了这些,但我可能会指出,目标是从字符串隐式转换为 int...
      • 由于您无法扩展内置类型,因此您无法为它们创建新的隐式转换。直觉上我不希望编译器允许这样做。似乎不确定编译器将查看哪些类来确定可能的隐式转换链。此外,此类代码的可读性似乎很糟糕,更不用说在将变量传递给具有该变量类型的重载以及可以隐式转换为的方法族时解决冲突。
      猜你喜欢
      • 2021-12-18
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多