显式强制转换运算符失败,并显示“未引用程序集”错误

时间:2014-04-10 11:07:37

标签: c# casting explicit

这是一个非常罕见的问题,确实存在很多变通方法,但我想了解实际发生了什么以及它为什么不起作用。
所以我在测试解决方案中有3个程序集,第一个程序集的类型为ClassA:

public class ClassA
{
    public string Name { get; set; }
}

第二个程序集引用第一个程序集并具有ClassB:

public class ClassB
{
    public string Name { get; set; }

    public static explicit operator ClassA(ClassB objB)
    {
        return new ClassA
        {
            Name = objB.Name
        };
    }
}

有一个显式运算符,可以强制转换为ClassA类型。让我们说我们不能出于某种原因使用继承,只使用转换作为将一种类型转换为另一种类型的便捷方式。

现在,最后一个程序集引用第二个程序集(而不是第一个程序集!)并且类型为ClassC:

public class ClassC
{
    public string Name { get; set; }

    public static explicit operator ClassB(ClassC objC)
    {
        return new ClassB
        {
            Name = objC.Name
        };
    }
}

使用显式强制转换运算符的原因与ClassB相同。

现在有趣的部分:如果我尝试在我的代码中从ClassC转换为ClassB,就像这样:

ClassC objC = new ClassC();
ClassB objB = (ClassB)objC;

我收到以下错误:

  

错误1类型' FirstAssembly.ClassA'在未引用的程序集中定义。您必须添加对程序集的引用" FirstAssembly,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'。

我可以轻松地创建ClassB的新实例,并使用ClassC实例中的值初始化它(就像我在显式转换运算符中一样),它可以正常工作。那么这里有什么问题?

1 个答案:

答案 0 :(得分:2)

在6.4.5用户定义的C#语言规范(版本4.0)的显式转换中,它读取:

  

处理从类型S到类型T的用户定义的显式转换   如下:

     

•确定类型S0和T0。如果S或T是可空类型,则S0和   T0是它们的基础类型,否则S0和T0等于S和   分别为。

     

•查找用户定义转换的类型集D.   运营商将被考虑。该集由S0组成(如果S0是a   类或结构),S0的基类(如果S0是一个类),T0(如果是T0   是一个类或结构),以及T0的基类(如果T0是一个类)。

它没有定义编译器将如何"找到类型集"但我认为它会搜索所有相关课程,寻找下一步的候选人:

  

•查找适用的用户定义和提升转换集   运算符,U。此集由用户定义和提升组成   类或语句声明的隐式或显式转换运算符   D中的结构转换自S包含或包含的类型   到T包含或包含的类型。如果U是空的,那么   转换未定义,发生编译时错误。

这会导致它尝试解析对ClassA的引用。