.NET 6预览功能:自定义接口实现+运算符支持遇CS8920错误的解决问询
你遇到的CS8920错误,核心原因是包含静态抽象成员的泛型接口(比如IAdditionOperators)要求TSelf类型参数必须是能够实现这些静态成员的类型,而接口本身无法实现静态成员——静态成员只能由类或结构体来实现,所以直接把IExtendedArray<T>作为TSelf传入IAdditionOperators会触发这个错误。
要实现你想要的“让接口支持+运算符”的需求,需要借鉴.NET中INumber<T>这类接口的设计思路:通过自引用泛型约束,让接口关联到具体的实现类,由实现类来承担TSelf的角色并实现静态运算符。
修改后的接口定义
调整IExtendedArray<T>和IExtendedFloatingPointArray<T>的泛型参数,引入代表实现类的TSelf参数,并添加自引用约束:
using System; using System.Runtime.Versioning; using System.Numerics; namespace InterfaceTest; [RequiresPreviewFeatures] public interface IExtendedArray<T, TSelf> : IAdditionOperators<TSelf, TSelf, TSelf> where T : INumber<T> where TSelf : IExtendedArray<T, TSelf> { Array Data { get; } } [RequiresPreviewFeatures] public interface IExtendedFloatingPointArray<T, TSelf> : IExtendedArray<T, TSelf> where T : IFloatingPoint<T> where TSelf : IExtendedFloatingPointArray<T, TSelf> { }
实现具体的数组类
接下来创建一个实现IExtendedArray<T, TSelf>的具体类,在类中实现+运算符重载:
[RequiresPreviewFeatures] public class NumericArray<T> : IExtendedArray<T, NumericArray<T>> where T : INumber<T> { public Array Data { get; } public NumericArray(Array data) { Data = data; } // 实现+运算符,满足IAdditionOperators的静态抽象成员要求 public static NumericArray<T> operator +(NumericArray<T> left, NumericArray<T> right) { if (left.Data.Length != right.Data.Length) throw new ArgumentException("Arrays must have the same length for addition"); T[] result = new T[left.Data.Length]; for (int i = 0; i < result.Length; i++) { result[i] = (T)left.Data.GetValue(i)! + (T)right.Data.GetValue(i)!; } return new NumericArray<T>(result); } }
为什么这样能解决问题
通过引入TSelf参数并添加where TSelf : IExtendedArray<T, TSelf>的自引用约束,我们把IAdditionOperators的TSelf指向了具体的实现类(比如NumericArray<T>)。而类是可以实现静态运算符的,这样就满足了IAdditionOperators对TSelf的约束要求,自然就不会再触发CS8920错误了。
另外,你的项目配置(EnablePreviewFeatures=true、引用System.Runtime.Experimental预览包)是正确的,和你安装的.NET 6 RC1版本匹配,不需要调整。
内容的提问来源于stack exchange,提问作者Dan

