我正试图从所有内置的INumber<T>
类中获取新的AdditiveIdentity
属性。所以我从int
开始(它应该返回0(。
然而,我发现很难真正达到这个值。。。(我已经安装了.NET 7 Preview 7(。
我本以为我能做到:
int additiveIdentity = int.AdditiveIdentity;
但这会导致在非静态上下文中访问它的错误(在静态方法中也不起作用
我试过在INumber<int>
:上访问它
int additiveIdentity = INumber<int>.AdditiveIdentity;
这引发了这个错误:
UnitTest1.cs(11,26(:[CS8926]静态虚拟或抽象接口成员只能在类型参数上访问。
假定此AdditiveIdentity
具有签名:
public abstract static override TResult AdditiveIdentity { get; }
我有点困惑于我如何才能真正阅读它…
我当然不必使用反射吗?
所以我找到了答案,这些只有在处理泛型类型参数时才能访问。
因此,一个很好的解决方法是:
public static T GetAdditiveIdentity<T>() where T: INumber<T> => T.AdditiveIdentity;
为了提供更多发生这种情况的上下文-对于Int32
,IAdditiveIdentity<TSelf,TResult>
接口是显式实现的(请参阅源代码(:
/// <inheritdoc cref="IAdditiveIdentity{TSelf, TResult}.AdditiveIdentity" />
static int IAdditiveIdentity<int, int>.AdditiveIdentity => AdditiveIdentity;
通过强制转换到接口来显式实现的普通实例接口方法所使用的方法不可用(至少是ATM(,因此您需要使用通用的解决方法:
static T GetAdditiveIdentity<T>() where T : IAdditiveIdentity<T, T> => T.AdditiveIdentity;
UPD
正如在对接口中静态抽象成员提案的讨论中所回答的那样,除了通用间接或使用反射之外,没有其他选择ATM。反射方法可以是这样的(严格来说,出于探索的目的,一般情况下通用间接方法应该更好(:
var properties = typeof(int).GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
var propertyInfo = properties.FirstOrDefault(t => t.Name.EndsWith(".AdditiveIdentity"));
var x = (int)propertyInfo.GetValue(null);