c#:Inherited / interface静态成员?

时间:2009-07-14 22:15:36

标签: c# oop inheritance interface static

有没有办法要求某个类有一个特定的抽象成员?像这样:

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

或许这个:

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

我想强制一种类型(通过继承或接口?)具有静态成员的方式。可以这样做吗?

4 个答案:

答案 0 :(得分:5)

您可以创建一个自定义属性,允许将要求强制为运行时保证。这不是一个完整的代码示例(您需要在应用程序启动时调用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;
        }
    }
}

答案 1 :(得分:4)

这是不可能的。由于抽象和虚方法调用通过其虚函数指针表存储在对象中,因此无法对其非实例成员强制执行任何接口要求。调用静态成员没有绑定对象,因此没有可用的虚拟指针表。

这不是限制,它只是如此。没有理由认为这是必要的或有用的。如果要强制实施接口,则必须通过实例成员执行此操作。

答案 2 :(得分:0)

不可能。也许你可以尝试这样的事情:

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();
    }
}

参考文献:

答案 3 :(得分:0)

假设类Base包含一个静态方法StaticMethod和一个实例方法InstanceMethod,它们都返回Int32。类派生会使用返回String的类似命名方法对这两个方法进行阴影处理。

如果将一个派生实例强制转换为Base并调用InstanceMethod,则该调用将使用Base.InstanceMethod,其返回类型为Int32。如果接受泛型类型T的实例,其中T继承Base,并在其上调用InstanceMethod,它同样会调用Base.InstanceMethod - 再次调用Int32。但T.StaticMethod的含义和返回类型应该是什么?如果想要Base.StaticMethod,就应该指定它。 T.StaticMethod还有什么用呢?