47

次のようなオブジェクトを安全にキャストするための拡張メソッドがあります。

public static T SafeCastAs<T>(this object obj) {
    if (obj == null)
        return default(T);

    // which one I should use?

    // 1. IsAssignableFrom
    if (typeof(T).IsAssignableFrom(obj.GetType()))
        return (T)obj;

    // 2. IsInstanceOfType
    if (typeof(T).IsInstanceOfType(obj))
        return (T) obj;

    // 3. is operator
    if (obj is T)
        return (T) obj;

    return default(T);
}

ご覧のとおり、3 つの選択肢があるので、どれを使用する必要がありますか? IsAssignableFrom実際、 、IsInstanceOfType、およびis演算子の違いは何ですか?

4

4 に答える 4

68

You use whatever you have the information for.

If you have an instance and a static type you want to check against, use is.

If you don't have the static type, you just have a Type object, but you have an instance you want to check, use IsInstanceOfType.

If you don't have an instance and you just want to check the compatibility between a theoretical instance of a Type and another Type, use IsAssignableFrom.

But really is seems like you are just re-implementing the as operator (except that yours would also work for non-nullable value types, which is usually not a big limitation).

于 2013-04-06T16:26:48.497 に答える
10

as値型と参照型で機能するバージョンの演算子を効果的に実装していると思います。

私は行きます:

public static T SafeCastAs<T>(this object obj)
{
    return (obj is T) ? (T) obj : default(T);
}

IsAssignableFromタイプでis動作し、インスタンスで動作します。あなたのケースでは同じ結果が得られるため、最も単純なバージョンの IMHO を使用する必要があります。

に関してはIsInstanceOfType: の観点から実装されているIsAssignableFromため、違いはありません。

Reflector を使用して の定義を調べることで、それを証明できますIsInstanceOfType()

public virtual bool IsInstanceOfType(object o)
{
    if (o == null)
    {
        return false;
    }
    return this.IsAssignableFrom(o.GetType());
}
于 2013-04-06T16:25:34.137 に答える