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
}

在另一个泛型类中,我依赖于基本自定义类型可以从字符串隐式转换为自身的事实。(转换发生在(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 自定义类型作为类型参数的泛型类的实例)时,我在转换为Tin的行处收到 InvalidCastException GetValue。我认为正在发生的是,为了让编译器能够接受我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 回答