当对象不是字符串时,如何将对象强制转换为字符串?

2 .net c# string casting

-Edit-替代问题/示例当B可以打印到A时,如何将A转换为A类对象?


我有A,B,C类.它们都可以隐式转换为字符串

public static implicit operator A(string sz_) {  ... return sz; }
Run Code Online (Sandbox Code Playgroud)

我有代码可以做到这一点

object AClassWhichImplicitlyConvertsToString

{
    ...
    ((IKnownType)(String)AClassWhichImplicitlyConvertsToString).KnownFunc()
}
Run Code Online (Sandbox Code Playgroud)

问题是,AClassWhichImplicitlyConvertsToString不是一个字符串,即使它可以被隐式地类型转换为一个字符串.我得到一个糟糕的演员异常.只要该类有一个运算符转换为字符串,我怎么说它的确定?

Dan*_*ker 8

目前几乎可以肯定在做什么是你正在试图做的更好的方法.如果您提供更多上下文,您将获得更多有用的答案.

如果不是(或同样)使你的类隐含地隐藏为字符串,你也给它们一个ToString覆盖,你可以说:

((KnownType)AClassBlah.ToString()).KnownFunc()
Run Code Online (Sandbox Code Playgroud)

但是,您将尝试将字符串转换为异常KnownType.所以我不得不问:你为什么要string在这种情况下通过?演员通常是一个丑陋的东西,让你觉得"也许我的设计需要有一天重构".它们不是您在类库中设计的推荐用法模式.它们是具有可预测行为的低级设施,因此没有办法(并且没有充分的理由提供方法)来覆盖显式转换所做的事情.

Update

从您的评论来看,您将运行时多态性和静态(编译时)转换混合在一起.它们混合得不太好.您以前是动态类型语言的用户吗?看起来你可能会.如果你有一个方法:

void FiddleWithObject(object obj)
{
    // whatever
}
Run Code Online (Sandbox Code Playgroud)

然后,该方法的作者没有关于可用操作的编译时知识obj.所以他们可以说:

void FiddleWithObject(object obj)
{
    if (obj is IFiddly)
    {
        // Cool
        obj.Fiddle();
    }
    else
        throw new Exception("Wrong type of object");
}
Run Code Online (Sandbox Code Playgroud)

然后,这会在编译时爆炸,而不是那些类IFiddly.但在静态类型语言中,您可以说:

void FiddleWithObject(IFiddly obj)
{
    obj.Fiddle(); 
}
Run Code Online (Sandbox Code Playgroud)

如果传递了错误类型的对象,这将在编译时爆炸,并且您不需要在运行时检查任何内容.更少的代码,更快发现的错误...这有多整洁?

隐式转换功能是运算符重载功能集的一部分.这些都与静态类型密切相关.它们在编译时根据对象的已知类型进行解析.因此,如果您不知道对象的实际类,则没有(内置)方法来调用它上面的运算符.它只是不与动态类型混合.

如果可以从IFiddly对象获取字符串(例如"名称"),则可以将其设置为该接口上的属性:

public interface IFiddly
{
    void Fiddle();
    string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)

或者(正如我之前提到的)你可以覆盖ToString任何对象,因为这是所有类最终继承virtualobject类的方法.所以说:

var str = someObject.ToString();
Run Code Online (Sandbox Code Playgroud)

您将调用ToString在任何类中定义的实现someObject.

综上所述:

  • 虚拟和抽象方法以及支持的接口:这些用于动态,运行时类型和多态.
  • 运算符和隐式转换重载(和泛型):这些用于编译时静态类型.
  • 演员都很恶心.