开发者

How do i cast an object to a string when object is not a string?

-Edit- Alternative question/example How do i cast A to object to class A when B can typcast to A?


I have class A, B, C. They all can implicitly convert to a string

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

I have code that does this

object AClassWhichImplicitlyConvertsToString

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

The problem is, AClassWhichImplicitlyConvertsToString isnt a string even though it can be typecast into one implicitly. I get a bad cast exception. How do i say its ok as long as the class has an o开发者_开发技巧perator to convert into a string?


There is almost certainly a better way of doing whatever it is you're trying to do. If you provide more context, you'll get more helpful answers.

If instead of (or as well as) making your classes implicitly covert to string you also give them a ToString override, you can then say:

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

However, you'll then get an exception on trying to cast a string into KnownType. So I have to ask: why are you trying to go via string in this situation? Casts are generally an ugly-ass thing that make you think "Maybe my design needs refactoring one day". They're not something you design into your class library as a recommended usage pattern. They're a low-level facility with predictable behaviour, so there is no way (and no good reason to provide a way) to override what an explicit cast does.

Update

Judging from your comment you are mixing together runtime polymorphism and static (compile time) conversion. They don't mix too well. Are you previously a user of dynamically typed languages? It seems like you might be. If you have a method:

void FiddleWithObject(object obj)
{
    // whatever
}

Then the author of that method has no compile-time knowledge of what operations are available on obj. So they can say:

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

This then blows up at compile time for classes that aren't IFiddly. But in a statically typed language, you can say:

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

This will blow up at compile time if the wrong kind of object is passed, and you don't need to check anything at runtime. Less code, bugs found sooner... how neat is that?

The implicit conversion feature is part of the operator overloading set of features. These are all very much tied to static types. They are resolved at compile time based on the known type of the object. So if you don't know the actual class of an object, there is no (built-in) way to call operators on it. It just doesn't mix with dynamic typing.

If it is possible to get a string (such as a "name") from an IFiddly object, then you can make it a property on that interface:

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

Or (as I noted before) you could just override ToString on any object, as that's a virtual method on the object class that all classes ultimately inherit from. So by saying:

var str = someObject.ToString();

You are going to be calling the ToString implementation defined in whatever class someObject is an instance of.

In summary:

  • virtual and abstract methods, and supported interfaces: these are for dynamic, runtime typing and polymorphism.
  • operator and implicit conversion overloading (and generics): these are for compile-time, static typing.
  • casts are disgusting.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜