I'm writing a very simple extension method that attempts to cast objects from one type to another. The intent of having this method is very similar to Int32.TryParse(string, out int), which allows the user to see 1) if the conversion succeeded, and 2) what the converted object is, all in one line.

Because this method will deal exclusively with class objects, it's possible that the object to be cast is actually null. Null can be cast to any nullable type (at least that's what it looks like based on my testing), so technically the method would always succeed in that situation. On the other hand, trying to convert null doesn't serve a lot of purpose and is usually a sign of things gone wrong. Therefore, my question is: in the case of the supplied object being null, should I return true (the cast succeeded) or false (did not succeed)?

This is (more or less) the method in question:

public static bool TryGetAs<T>(this object obj, out T output) where T : class
{
    output = null;
    if (obj == null)
        return [true or false];

    output = obj as T;
    return output != null;
}
有帮助吗?

解决方案

Look to what your clients want, and try to provide an abstraction that is useful. And if you are your own client, try to think critically about what you want as a client rather than as the implementer.

I would assert that at the point someone calls this they are now only interested in whether the item provides the API of the type (which null doesn't).

If you return true for null, your clients are IMNSHO very likely to have to do their own null check in conjunction with, and either before or after using, your method. Only in vary rare cases will they not need their own null check.

If you return false, they won't have to do their own null check.

Still, have a look at how clients use the function, and you'll have your answer.

其他提示

If your input parameter is null you are not able to decide what is the right return value. Any return value would be as good as the other. It doesn't matter if it is null, true, false or "foobar".

Getting a special type of object from an arbitrary object is really weired. I really doubt the usecase. The point is that your generic method uses a language specific resolution that only works with related types... or at least it only makes sense with related types...

The difference between your method and the parse-method is: the int parse method provides a concrete algorithm to resolve the integer from a String. This algorithm is semantically well-defined.

Your algorithm may be technically well-defined but not semantically. You can easily see that if you try to put in an object of a custom type of yours and you want to return a String. I cannot imagine how this can make sense. How can this method do better than a toString method on the source object itself? The provided algorithm has no semantics.

So if you make the method generic and your algorithm does only make sense for SOME inputs and SOME outputs why should I confuse users of this method by pretending that it is doing beneficial stuff?

Avoid such kind of methods that pretend generic but are not.

许可以下: CC-BY-SA归因
scroll top