【问题标题】:user-defined conversion must convert to or from the enclosing type用户定义的转换必须与封闭类型相互转换
【发布时间】:2014-01-15 00:23:43
【问题描述】:

有人可以帮我吗?

错误:用户定义的转换必须与封闭类型相互转换:

public static explicit operator E(M value)
{
    return value.Value;
}
public static implicit operator M(E value)
{
    return new M { Value = value };
}

例子:

基础模型

public abstract class BaseModel<E, M>
    where E : class, new()
    where M : BaseModel<E, M>, new()
{
    public BaseModel()
    {
        this.Value = new E();

    }

    public static explicit operator E(M value)
    {
        return value.Value;
    }
    public static implicit operator M(E value)
    {
        return new M { Value = value };
    }

    public E Value { get; set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

用法:

public class Usuario
{
    public int PK_USUARIO { get; set; } //IDENTITY(1,1) NOT NULL,
    public bool USUA_NR_ATIVO { get; set; } //bit NOT NULL,
}

型号:

    [DisplayName("Status")]
    [System.ComponentModel.Editor(typeof(bool), typeof(bool))]
    public bool Ativo
    {
        get { return Value.USUA_NR_ATIVO; }
        set { Value.USUA_NR_ATIVO = value; }
    }

【问题讨论】:

标签: c# .net


【解决方案1】:

我明白你在做什么。不幸的是,.NET 不允许在基类中定义转换运算符。它们只能转换为确切的类型。参数或返回类型必须与当前类完全匹配。

因此必须在派生类M 中定义转换运算符。 当然,这违反了 DRY 原则,但我不知道如何实现泛型转换运算符。我认为这根本不可能,因为泛型转换通常适用于无限数量的类型。

在第一种情况下,您可能会接受

public static explicit operator E(BaseModel<E,M> value)
{ return value.Value;
}

但是逆变换不起作用。这意味着E 可以转换为从BaseModel&lt;E,M&gt; 派生的any 类型。这可能不是您想要的。

但是,如果您可以接受上述通用转换,则您只需要在任何派生类中定义 一个 运算符。至少这不那么干燥。


一些进一步的评论: 您还应该知道,使用where X : new() 非常慢,因为它会调用Activator.CreateInstance,而Activator.CreateInstance 本身使用反射来调用构造函数。

您可以通过使用带有E 参数的构造函数和缓存的编译表达式来调用此构造函数来避免这种情况。这避免了除了第一个实例之外的每个实例的反射调用。

【讨论】:

    【解决方案2】:

    您需要将此代码保留在将要转换的类中。如下例所示。

    class MyClass {
        public static explicit operator xxx(string s) { // details }
        public static implicit operator string(xxx x) { // details }
    }
    

    如果你的类没有被创建的可能性,请尝试使用可以工作的部分类

    【讨论】:

    • 您是否从评论中链接的副本的答案中复制了该示例?我的意思是,这很好,我想,但你至少能做的就是将功劳归功于其他回答者。
    猜你喜欢
    • 2011-04-02
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多