How to access static interface member when the interface is implemented explicitly
Asked Answered
D

1

7

I wonder if I found the right solution how to access static property/method of the interface when the interface is implemented explicitly.

In .NET 7 interface can define static abstract members. For example System.Numerics.INumberBase interface define:

public static abstract TSelf One { get; } 

This interface is explicitly implemented by various numeric types, e.g. System.Int32.

/// <inheritdoc cref="INumberBase{TSelf}.One" />
static int INumberBase<int>.One => One;

Now trying to access int.One value.

Here is what I tried:

using System;
                    
public class Program
{
    public static void Main()
    {
        // Does not compile - because One is implemented explicitly
        // Compiler: 'int' does not contain a definition for 'One' 
        Console.WriteLine(int.One);

        // Does not compile
        // Compiler: A static virtual or abstract interface member can be accessed only on a type parameter.
        Console.WriteLine(System.Numerics.INumberBase<int>.One);
        
        // Compiles
        Console.WriteLine(GetOne<int>());
    }
    
    private static T GetOne<T>() where T : System.Numerics.INumberBase<T> => T.One;
}

Is the GetOne method the only solution (without using reflection) or am I missing something?

Debouchment answered 30/1, 2023 at 15:51 Comment(2)
Good question. I'm also wondering about the design decision behind the explicit interface implementation.Siddon
Great question! I am stumped too by the lack of a "clean" way to access interface static members.Burse
H
5

This was discussed in the comments to the proposal for static abstract members in interfaces - currently there are no other options except for the generic indirection (i.e. GetOne<T>() approach) or using reflection for explicitly implemented static abstract interface members.

Just for completeness - using reflection (with not perfect search by member name) approach:

var properties = typeof(int).GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
var propertyInfo = properties.FirstOrDefault(t => t.Name.EndsWith(".One"));
var one = (int)propertyInfo.GetValue(null);
Haemic answered 30/1, 2023 at 15:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.