Как получить доступ к реализованным статическим абстрактным элементам интерфейса типа, имея только тип без использования отражения?
Как получить доступ к реализованным статическим абстрактным элементам интерфейса типа, имея только тип и используя сам тип интерфейса? Как это сделать? Я не говорю о доступе к статическим членам через отражение.
пример:
public interface ISomeInterface
{
static int SomeProperty {get; set;}
}
public class SomeClass : ISomeInterface
{
static abstract int SomeProperty {get; set;} = 2;
}
var implementingType = typeof(SomeClass);
ISomeInterface interface = /* How? */
Есть ли способ получить значение без использования обычного способа, используя отражение для доступа к статическому члену, подобному этому
void Method {
var value = typeof(SomeClass).GetProperty("SomeProperty").GetValue(null);
value = typeof(ISomeInterface).GetProperty("SomeProperty").GetValue(null);
}
Приведение - это концепция, которая работает только с экземплярами, поэтому ее нельзя использовать для определений типов.
2 ответа
Во-первых, ключевое слово abstract должно применяться к методу интерфейса, а не к классу. Если метод интерфейса не является абстрактным, ваш вопрос в любом случае бессмысленен.
Статические методы абстрактного интерфейса здесь неуместны, потому что вы не можете вызывать любой статический метод без указания имени типа, другими словами, вы не можете вызывать статические методы для экземпляров.
Ниже приведен мой подход к вашему вопросу, который почти так же быстр, как прямой вызов (хотя он не может быть встроен). Используя статические указатели управляемых функций только для чтения для хранения адресов сконструированных методов, мы можем избежать создания объекта делегата, а адрес метода будет рассматриваться как постоянный значение jit, но здесь не нужно усложнять..
class Program
{
public interface ISomeInterface
{
abstract static int SomeProperty { get; set; }
}
public class SomeClass : ISomeInterface
{
static int ISomeInterface.SomeProperty { get; set; } = 2;
}
public class SomeClass2 : ISomeInterface
{
static int ISomeInterface.SomeProperty { get; set; } = 3;
}
public static int GetProp<T>() where T : ISomeInterface
{
return T.SomeProperty;
}
public static void Main(string[] args)
{
var obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(SomeClass)) as ISomeInterface;
//obj.SomeProperty <= no hopes here..
var methodDefinitation = typeof(Program).GetMethod(nameof(GetProp), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
var @delegate = methodDefinitation.MakeGenericMethod(typeof(SomeClass)).CreateDelegate(typeof(Func<int>)) as Func<int>;
var @delegate2 = methodDefinitation.MakeGenericMethod(typeof(SomeClass2)).CreateDelegate(typeof(Func<int>)) as Func<int>;
var result1 = @delegate(); //2
var result2 = @delegate2(); //3
}
}
Поразмыслив еще раз над вопросом и над тем, что я хотел сделать, я пришел к отрицательному ответу.
Невозможно использовать тип интерфейса для доступа к переопределенному значению статического абстрактного члена интерфейса в реализующем классе, кроме отражения и доступа к статической опоре с помощью
GetProperty(name).GetValue(null)
Изменить: ТАК не место для предложений, но я подумал о чем-то вроде:
ISomeInterface a = (ISomeInterface)typeof(SomeImplementingClass);
var value = a.SomeInterface.SomeProperty;
или
var value = typeof(SomeImplementingClass).As<ISomeInterface>().SomeProperty;
var value = ISomeInterface.FromType<SomeImplementingClass>().SomeProperty;
... где '.As()' выдает исключение, если интерфейс не реализован. Оба этих примера не поддерживаются.