在抽象类与其实现之间实现版本检查

发布于 2024-08-26 16:08:55 字数 1229 浏览 6 评论 0原文

我有这个抽象类和具体实现(它们位于不同的程序集中):

public abstract class MyAbstractClass
{
    private static readonly int MyAbstractClassVersion = 1;
    public abstract int ImplementedVersion  { get; }

    protected MyAbstractClass()
    {
        CheckVersion();
    }

    private void CheckVersion()
    {
        var message =
            string.Format(
            "MyAbstractClass implements Version {0}, concrete is Version {1}",
            RepositoryVersion, ImplementedVersion);
        if (!MyAbstractClassVersion.Equals(ImplementedVersion))
          throw new InvalidOperationException(message);
    }
}


public class ConcreteClass : MyAbstractClass
{
    public ConcreteClass() : base() {
        // ConcreteClass is guaranteed to have
        // a constructor that calls the base constructor
        // I just simplified the example
}

    public override int ImplementedVersion
    {
        get { return 2; }
    }
}

如您所见,我从抽象构造函数调用 CheckVersion() ,以摆脱“基本构造函数中的虚拟成员调用”消息,但我不确定如果这真的是这样做的方法的话。当然,它有效,但这并不意味着它永远有效,不是吗?

另外,我想知道是否可以从 CheckVersion() 函数中获取具体类型的名称?

我知道添加新的抽象成员无论如何都会强制出现错误(System.TypeLoadException),并且我不确定是否需要这种类型的严格版本控制,但我只是好奇仅给出抽象类和一个实现(我知道我可以通过使用接口和/或工厂模式来做到这一点)。

I have this abstract class and concrete implementation (they are in different assemblies):

public abstract class MyAbstractClass
{
    private static readonly int MyAbstractClassVersion = 1;
    public abstract int ImplementedVersion  { get; }

    protected MyAbstractClass()
    {
        CheckVersion();
    }

    private void CheckVersion()
    {
        var message =
            string.Format(
            "MyAbstractClass implements Version {0}, concrete is Version {1}",
            RepositoryVersion, ImplementedVersion);
        if (!MyAbstractClassVersion.Equals(ImplementedVersion))
          throw new InvalidOperationException(message);
    }
}


public class ConcreteClass : MyAbstractClass
{
    public ConcreteClass() : base() {
        // ConcreteClass is guaranteed to have
        // a constructor that calls the base constructor
        // I just simplified the example
}

    public override int ImplementedVersion
    {
        get { return 2; }
    }
}

As you see, I call CheckVersion() from the abstract constructor, to get rid of the "virtual member call in base constructor" message, but I am not sure if that's really the way to do it. Sure, it works, but that doesn't mean it will always work, will it?

Also, I wonder if I can get the name of the Concrete Type from the CheckVersion() function?

I know that adding new abstract members will force an error anyway (System.TypeLoadException) and I'm not sure if I want this type of strict Versioning, but I'm just curious how it would be done properly given only the abstract class and an implementation (I know I could do it by using interfaces and/or a Factory pattern).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

宛菡 2024-09-02 16:08:55

好吧,你只是愚弄了静态分析 - 你仍然在 ctor 中进行虚拟调用。如果在构造过程中需要它,也许这应该是子类传递下来的必需的基构造函数值:

protected BaseType(int version) { /* store etc */ }

public DerivedType() : base(3) {...}

或者也许在编译时固定的东西中执行 - 属性:

[YourVersion(3)]
public class DerivedType {...}

并通过反射查找:

YourVersionAttribute attrib = (YourVersionAttribute)
     Attribute.GetCustomAttribute(GetType(), typeof(YourVersionAttribute));
int version = attrib == null ? -1 : attrib.Version;

Well, you're only fooling the static analysis - you're still doing a virtual call in the ctor. If it is needed during the ctor, perhaps instead this should be a required base-constructor value, that subclasses pass down:

protected BaseType(int version) { /* store etc */ }

public DerivedType() : base(3) {...}

Or perhaps do it in something that is fixed at compile - attributes:

[YourVersion(3)]
public class DerivedType {...}

and look this up via reflection on:

YourVersionAttribute attrib = (YourVersionAttribute)
     Attribute.GetCustomAttribute(GetType(), typeof(YourVersionAttribute));
int version = attrib == null ? -1 : attrib.Version;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文