1

ここのソリューションで再現した問題のトラブルシューティングを行っています。

問題は、文字列からそれ自体に暗黙的にキャストできるいくつかのカスタムタイプを使用していることです。カスタムタイプの1つは他から継承します。

public class CustomType
{
    public string InnerString { get; protected set; }

    public CustomType(string s)
    {
        InnerString = s;
    }

    #region Operator Overloads
    public static implicit operator CustomType(string s)
    {
        if (s == null)
            throw new ArgumentNullException();
        return new CustomType(s);
    }
    public static implicit operator string(CustomType value)
    {
        if (value == null)
            return null;
        return value.InnerString;
    }
    #endregion
}


public class SubCustomType : CustomType
{
    public SubCustomType(string s)
        : base(s)
    {
        // Nada
    }

    #region Operator Overloads
    public static implicit operator SubCustomType(string s)
    {
        if (s == null)
            throw new ArgumentNullException();
        return new SubCustomType(s);
    }
    public static implicit operator string(SubCustomType value)
    {
        if (value == null)
            return null;
        return value.InnerString;
    }
    #endregion
}

別の汎用クラスでは、基本カスタム型が文字列からそれ自体に暗黙的にキャストできるという事実に依存しています。(キャストは.is文字列の行で発生します(T)this.Rtf.Rtf)(この問題が発生したときに使用していたので、ジェネリッククラスは私の場合はRichTextBoxのサブクラスです。)

public class CustomRichTextBox<T> : Forms.RichTextBox
    where T : CustomType
{
    public object GetValue()
    {
        /// This line throws:
        /// InvalidCastException
        /// Unable to cast object of type 'TestCustomTypesCast.CustomType' to type 'TestCustomTypesCast.SubCustomType'.
        return (T)this.Rtf;
    }
}

public class SubCustomRichTextBox : CustomRichTextBox<SubCustomType>
{
}

SubCustomRichTextBox(タイプ引数としてSUBカスタムタイプを持つジェネリッククラスのインスタンス)を使用すると、でキャストした行でInvalidCastExceptionが発生TGetValueます。私が起こっていると思うのは、コンパイラがT文字列からキャストするために使用しているという事実に問題がないようにするために、コンパイラはCustomTypeキャストのオーバーロードを調べているということです。しかし、実際の型引数としてのサブクラスを使用する場合でもCustomType、コンパイラーSubCustomType.CustomType(string s)は正しいSubCustomType.SubCustomType(string s)メソッドではなく、キャストを実行しようとします。

誰かがこの問題を解決する方向に私を向けることができますか?同じコードを再利用できるので、汎用クラスを使用したいと思います。ジェネリックスを使用できない場合は、のいくつかのサブクラスでコードを複製する必要がありますCustomRichTextBox<T>。ありがとう。

4

1 に答える 1

1

演算子のオーバーロードは静的であり、基本的に仮想動作を取得しようとしているため、これは困難になります。

これを試して:

public class CustomRichTextBox<T> : Forms.RichTextBox
    where T : CustomType, new()
{
    public object GetValue()
    {
        T t = new T();
        t.InnerString = this.Rtf;
        return t;
    }
}

new()タイプ制約に追加したことに注意してください。また、InnerStringを公開設定可能にする必要がありました。

余談ですが、リターンタイプをGetValue()beにしますT。それはより良いAPIかもしれません。

于 2012-05-17T21:45:54.067 に答える