gpt4 book ai didi

C# 替代虚拟静态方法和静态子类

转载 作者:太空狗 更新时间:2023-10-29 19:39:34 24 4
gpt4 key购买 nike

每当我阅读有关 RE this 或类似静态继承主题的问题时,回复通常是不支持(我们知道),并且给出的原因是因为这是一个糟糕的设计并且可能有更好的方法来做到这一点。我很想找到一种更好的方法,因此愿意接受所有建议 - 这就是我正在尝试做的事情。

我有一个没有实例数据的类。所有的方法都是静态的。我们称此 class BaseStatic。我现在想要一个新的静态类(当然有好几个,但让我们坚持一个)继承自这个静态类并添加一些新的静态方法,我们称之为 SubStatic

我希望消费者能够写的是:

SubStatic.MethodFromSub();

还有

SubStatic.MethodFromBase();

我知道我也可以写:

BaseStatic.MethodFromBase()

明确但随后消费者必须知道哪个类实现了哪些方法。我不能通过继承来做到这一点,因为我不能从一个静态类继承另一个静态类。那么更好的方法是什么?

现在,我知道我可以将这些类作为实例类,并且可以将所有方法定义为静态的——这将给我上述的行为,但会导致其他问题,即:

  1. 当我执行此操作时:SubStatic.MethodFromBase() SubStatic 静态构造函数未被调用,因为该方法在父静态类中运行(父的调用静态构造函数)

  2. 如果其中一个静态父方法需要调用子类可以覆盖的另一个方法,我需要在子类中使用虚拟静态方法。我知道我不能拥有。

显然设计太差了 - 谁能帮我重做一下?我知道我可以使用实例继承并正确使用虚拟方法(我已经以这种方式工作)但是客户端代码总是必须创建一个实例(或者我想是一些单例)。

最佳答案

这可以满足您的目的,但我当然会包括一些异常处理,并在其实现过程中附上大量说明其工作原理和工作方式的文档。

Base 的静态构造函数时运行(一次)当前在应用程序域中加载的所有程序集都被编目,选择从 Base 派生的类型.迭代这些,我们运行静态构造函数。但值得注意的是,这不再保证每个实现的 cctor 将恰好运行一次,必须向它们中的每一个添加逻辑以重新做出该断言。此外,在 Base 的 cctor 之后加载的类型已运行不会通过调用 Base 中的方法进行初始化

要模拟虚拟方法,请使用 new隐藏基本方法的关键字。您可以通过使用声明类的名称对其进行限定来调用基方法(如示例中的类 B)

using System;
using System.Linq;
using System.Runtime.CompilerServices;

namespace ConsoleApplication6
{
public class Base
{
static Base()
{
Console.WriteLine("Base cctor");

var thisType = typeof (Base);
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes());
var derivations = loadedTypes.Where(thisType.IsAssignableFrom);

foreach(var derivation in derivations)
{
RuntimeHelpers.RunClassConstructor(derivation.TypeHandle);
}
}

public static void Foo()
{
Console.WriteLine("Bar");
}
}

public class A : Base
{
static A()
{
Console.WriteLine("A cctor");
}
}

public class B : Base
{
static B()
{
Console.WriteLine("B cctor");
}

public new static void Foo()
{
Console.WriteLine("Bar!!");
Base.Foo();
}
}

class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}

编辑

另一个选择在于 CRTP(或 C# 范例中的 CRGP)或奇怪的重复模板(通用)参数模式

using System;
using System.Runtime.CompilerServices;

namespace ConsoleApplication6
{
public class Base<T>
where T : Base<T>
{
static Base()
{
RuntimeHelpers.RunClassConstructor(typeof (T).TypeHandle);
}

public static void Foo()
{
Console.WriteLine("Bar");
}
}

public class Base : Base<Base>
{
}

public class A : Base<A>
{
static A()
{
Console.WriteLine("A cctor");
}
}

public class B : Base<B>
{
static B()
{
Console.WriteLine("B cctor");
}

public new static void Foo()
{
Console.WriteLine("Bar!!");
Base<B>.Foo();
}
}

class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}

在这种情况下,当我们在 A 上调用静态方法时我们真的在 Base<A> 上调用它这不同于 Base<B>Base所以我们可以实际确定该方法是如何调用的并运行适当的 cctor。

关于C# 替代虚拟静态方法和静态子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13005309/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com