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

时间:2010-03-21 10:58:58

标签: c# .net string casting

-Edit-替代问题/示例How do i cast A to object to class A when B can typcast to A?


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

public static implicit operator A(string sz_) {  ... return sz; }

我有代码执行此操作

object AClassWhichImplicitlyConvertsToString

{
    ...
    ((IKnownType)(String)AClassWhichImplicitlyConvertsToString).KnownFunc()
}

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

1 个答案:

答案 0 :(得分:8)

几乎可以肯定是一种更好的方式来做任何你想要做的事情。如果您提供更多上下文,您将获得更多有用的答案。

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

((KnownType)AClassBlah.ToString()).KnownFunc()

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

Update

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

void FiddleWithObject(object obj)
{
    // whatever
}

然后,该方法的作者没有编译时知道obj上可用的操作。所以他们可以说:

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

然后,在编译时,对于非IFiddly的类,这会爆炸。但是在静态类型的语言中,你可以说:

void FiddleWithObject(IFiddly obj)
{
    obj.Fiddle(); 
}

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

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

如果可以从IFiddly对象获取字符串(例如“name”),那么可以将其作为该接口上的属性:

public interface IFiddly
{
    void Fiddle();
    string Name { get; }
}

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

var str = someObject.ToString();

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

总结:

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