假设抽象类型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;
}
}
上述任何其他替代方法,以提供类型的广义隐式装箱?
答案 0 :(得分:3)
使您的班级A<T, J>
能够正常工作的最接近的是:
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<T, J>
而失败。因此,能够依靠where J : A<T, J>, 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);
}
}
结果代码中的净差异非常小,但您必须进行显式转换(对于代码可读性和维护而言,这不是一件坏事。)