【问题标题】:Abstract Generic Implicit Conversion to a Derived Type, Error?抽象泛型隐式转换为派生类型,错误?
【发布时间】:2015-02-13 00:17:02
【问题描述】:

假设抽象类型 A 的定义如下:

public abstract class A<T, J> : where J : A<T, J>, new()
{
    public virtual T Value { get; set; }

    //Error: User-defined conversion must convert to or from the enclosing type
    public static implicit operator J(T value)
    {
        return new J
        {
            Value = value
        };
    }
}

隐式运算符导致编译器发出错误“用户定义的转换必须转换为封闭类型或从封闭类型转换。”

隐式运算符转换为封闭类型的派生类型。这是 C# 的错误还是限制?

我正在尝试将类型 T 的拳击概括为 J。

更新:

继续那个错误,我尝试了以下方法:

public abstract class A<T, J> : where J : Primary<T, J>, new()
{
    public virtual T Value { get; set; }

    public static implicit operator A<T, J>(T value)
    {
        return new J
        {
            Value = value
        };
    }

    public static implicit operator J(A<T, J> value)
    {
        return value as J;
    }
}

这确实可以防止编译器错误(如预期的那样),尽管它随后会强制进行显式转换。这是不可取的。

基本上,我希望能够做到以下几点:

public class B { }

public class C : A<B, C> 
{ 
    public C Foo(B b)
    {
        return b;
    }
}

上述方法的任何其他替代方法可以提供类型的通用隐式装箱吗?

【问题讨论】:

    标签: c# generics abstract implicit-conversion


    【解决方案1】:

    最接近您的班级A&lt;T, J&gt; 工作的是:

    public class A<T, J> where J : A<T, J>, new()
    {
        public virtual T Value { get; set; }
    
        public static implicit operator A<T, J>(T value)
        {
            return new A<T, J>
            {
                Value = value
            };
        }
    }
    

    但是一旦你标记了这个abstract,它就不会工作,因为new A&lt;T, J&gt;。因此,可以依靠where J : A&lt;T, J&gt;, new() 来表示您正在创建派生类型。但这不再是有效的 c# 语法。

    底线是你不能做你希望做的隐式转换。

    您可以进行显式转换:

    public abstract class A<T, J> where J : A<T, J>, new()
    {
        public virtual T Value { get; set; }
    
        public static J Convert(T value)
        {
            return new J
            {
                Value = value
            };
        }
    }
    

    现在这可以工作了:

    public class B { }
    
    public class C : A<B, C> 
    { 
        public C Foo(B b)
        {
            return C.Convert(b);
        }
    }
    

    生成的代码几乎没有净差异,但您必须进行显式转换(这对代码的可读性和维护来说并不是一件坏事。)

    【讨论】:

      猜你喜欢
      • 2016-11-15
      • 1970-01-01
      • 2014-02-19
      • 2014-09-22
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多