tags:

views:

39

answers:

1

So I've written a quick bit of code to help quickly convert between business objects and view models. Not to pimp my own blog, but you can find the details here if you're interested or need to know.

One issue I've run in to is that I have a custom collection type, ProductCollection, and I need to turn that in to a string[] in on my model. Obviously, since there is no default implicit cast, I'm getting an exception in my contract converter.

So, I thought I would write the next little bit of code and that should solve the problem:

public static implicit operator string[](ProductCollection collection) {
    var list = new List<string>();
    foreach (var product in collection)
    {
        if (product.Id == null)
        {
            list.Add(null);
        }
        else
        {
            list.Add(product.Id.ToString());
        }
    }
    return list.ToArray();
}

However, it still fails with the same cast exception. I'm wondering if it has something to do with being in reflection? If so, is there anything that I can do here?? I'm open to architectural solutions, too!

+1  A: 

First, the implicit operator allows for implcit conversions (no casting directive). explicit operators operate on casts.

Nonetheless, that isn't the real issue here. Operators are not polymorphic (they're overloaded, not overridden); that is, in order to take advantage of an overloaded operator, you must be referring to a class in the context of the class that defines it.

For example:

public class Foo
{
    public static implicit operator Bar(Foo foo) { return new Bar(); }
}

public class Bar { }

...

void Baz()
{
    Foo foo = new Foo();

    Bar bar = foo; // OK

    object baz = foo;

    bar = baz; // won't compile, there's no defined operator at the object level

    bar = (Bar)baz; // will compile, but will fail at runtime for the same reason
}

Without knowing what you're doing and how you're doing it, I can't offer much in the way of a meaningful alternative. Some ideas, however:

  1. Override ToString (or use a common base class / interface for your entities with your own version if you don't want to use ToString) on your entities, then enumerate the collections generically to construct your string array
  2. Provide a ToStringArray function on your collections (by way of a common base class or interface) that does something similar

The biggest point is not to use operators for this purpose; they won't help you.

Adam Robinson
This is a very excellent explanation. Thanks! This is an obscure bit of the language that I was unaware of until looking for a solution for this.
Brad Heller