c #: Унаследованный / статический член интерфейса? - PullRequest
2 голосов
/ 15 июля 2009

Есть ли способ требовать, чтобы класс имел определенный абстрактный член? Примерно так:

public interface IMaxLength
{
    public static uint MaxLength { get; }
}

Или, может быть, это:

public abstract class ComplexString
{
    public abstract static uint MaxLength { get; }
}

Я бы хотел, чтобы у типа (через наследование или через интерфейс?) Был статический член. Можно ли это сделать?

Ответы [ 4 ]

5 голосов
/ 15 июля 2009

Вы можете создать пользовательский атрибут, который позволяет применять требование в качестве гарантии времени выполнения. Это не полный пример кода (вам нужно вызвать VerifyStaticInterfaces при запуске вашего приложения, и вам нужно заполнить помеченное TODO), но он показывает основы.

Я предполагаю, что вы спрашиваете об этом, чтобы гарантировать успешные вызовы именованных методов на основе отражения.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)]
internal sealed class StaticInterfaceAttribute : Attribute
{
    private readonly Type interfaceType;

    // This is a positional argument
    public StaticInterfaceAttribute(Type interfaceType)
    {
        this.interfaceType = interfaceType;
    }

    public Type InterfaceType
    {
        get
        {
            return this.interfaceType;
        }
    }

    public static void VerifyStaticInterfaces()
    {
        Assembly assembly = typeof(StaticInterfaceAttribute).Assembly;
        Type[] types = assembly.GetTypes();
        foreach (Type t in types)
        {
            foreach (StaticInterfaceAttribute staticInterface in t.GetCustomAttributes(typeof(StaticInterfaceAttribute), false))
            {
                VerifyImplementation(t, staticInterface);
            }
        }
    }

    private static void VerifyInterface(Type type, Type interfaceType)
    {
        // TODO: throw TypeLoadException? if `type` does not implement the members of `interfaceType` as public static members.
    }
}

internal interface IMaxLength
{
    uint MaxLength
    {
        get;
    }
}

[StaticInterface(typeof(IMaxLength))]
internal class ComplexString
{
    public static uint MaxLength
    {
        get
        {
            return 0;
        }
    }
}
4 голосов
/ 15 июля 2009

Это невозможно. Поскольку абстрактные и виртуальные вызовы методов хранятся в объекте , хотя в его таблице указателей виртуальных функций нет никакого способа, которым можно было бы применить какое-либо требование интерфейса к его элементам, не являющимся экземплярами. Вызов статического члена не связан с объектом, поэтому нет таблицы виртуальных указателей.

Это не ограничение, просто оно есть. Нет никаких причин, почему это было бы когда-либо необходимо или полезно. Если вы хотите применить интерфейс, вы должны сделать это через членов экземпляра.

0 голосов
/ 28 июля 2011

Предположим, что класс Base включает статический метод StaticMethod и метод экземпляра InstanceMethod, оба из которых возвращают Int32. Класс Производные тени обоих методов с одноименными методами возвращают String.

Если кто-то приводит экземпляр производного к Base и вызывает InstanceMethod, при вызове будет использоваться Base.InstanceMethod, тип возвращаемого значения которого - Int32. Если принять экземпляр универсального типа T, где T наследует Base, и при этом вызвать InstanceMethod, он также вызовет Base.InstanceMethod - снова Int32. Но каков должен быть смысл и тип возвращаемого значения T.StaticMethod? Если кто-то хочет Base.StaticMethod, нужно указать это. Что еще может значить T.StaticMethod?

0 голосов
/ 15 июля 2009

Не возможно. Может быть, вы можете попробовать что-то вроде этого:

public class Base
{
    public struct MyStruct
    {
        public static int x = 100;
        public static int XX()
        {
            return 200;
        }
    }
}

public class Derived : Base
{
    public void test()
    {
        int x = Derived.MyStruct.x;
        int XX = Derived.MyStruct.XX();
    }
}

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...