是的,如果您不介意定义代理实例调用静态方法的新类型,您可以 - 某种程度上说:
虽然interface 只能声明 instance 成员,但您可以使用 C# 的泛型使用几个简单的技巧,无需反射,即可完成您所追求的(并且无需求助于 Java -style AbstractFactoryBeanFactory 设计模式过度使用)。
我们可以做的是定义一个单独的struct(即一个值类型),其中包含调用我们想要的静态成员的实例成员。
所以如果我们有这个接口:
interface IStaticFunctionality
{
void DoSomethingWithoutAnObjectInstance();
}
...我们想做这样的事情:
void AGenericMethodThatDoesntHaveAnInstanceOfT<T>()
{
T.DoSomethingWithoutAnObjectInstance();
}
...那么我们可以这样做:
void AGenericMethodThatDoesntHaveAnInstanceOfT<T>()
where T : struct, IStaticFunctionality
{
T t = default;
t.DoSomethingWithoutAnObjectInstance();
// Note the above code uses `T t default;` instead of `T t = new T()`.
// This is because the C# compiler currently replaces `new T()` with `Activator.CreateInstance<T>()` in the generated bytecode.
// This has poor performance compared to `default(T)` or a normal non-generic constructor call, but the compiler does this because it's a workaround for a design-bug back in C# 6.0: https://devblogs.microsoft.com/premier-developer/dissecting-the-new-constraint-in-c-a-perfect-example-of-a-leaky-abstraction/
}
因此,如果我们使用 static void DoSomethingWithoutAnObjectInstance 方法有不同的类型,我们只需要为每个类型定义 struct 的 IStaticFunctionality 实现:
class Foo
{
public static void DoSomethingWithoutAnObjectInstance()
{
Console.WriteLine("foo");
}
struct Static : IStaticFunctionality
{
void DoSomethingWithoutAnObjectInstance() => Foo.DoSomethingWithoutAnObjectInstance();
}
}
class Bar
{
public static void DoSomethingWithoutAnObjectInstance()
{
Console.WriteLine("bar");
}
struct Static : IStaticFunctionality
{
void DoSomethingWithoutAnObjectInstance() => Bar.DoSomethingWithoutAnObjectInstance();
}
}
那么AGenericMethodThatDoesntHaveAnInstanceOfT<Foo> 的呼叫站点实际上看起来像:
AGenericMethodThatDoesntHaveAnInstanceOfT<Foo.Static>();