如何存储对静态类的引用?

Joa*_*nge 13 .net c# compiler-construction

所以类似于:

public static class StaticClass {}

public class InstanceClass
{
    static StaticClass StaticProperty {get;set;}

    public InstanceClass()
    {
        InstanceClass.StaticProperty = StaticClass;
    }
}
Run Code Online (Sandbox Code Playgroud)

我以为可以做到这一点,但编译器返回这些错误:

静态类型不能用作参数

静态类型不能用作返回类型

编辑:我知道这不起作用,但为什么?我想StaticClass存储在内存中的某个地方,因此可以允许其他变量在同一个内存中引用它,对吧?

EDIT2:其中一个用例是这样的:

假设您收集了5个不同的静态类,没有源代码,并且它们执行通用的东西,因此您希望通过单个静态类方便地访问它们.你可以这样做:

public static class GenericStuff
{
    public LinearAlgebra LinearAlgebra {get;set;}
    public StringUtilities String {get;set;}
    public GeometryOps Geometry {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

并使用它像:

GenericStuff.LinearAlgebra.GetAngleBetweenVectors(v0, v1);
Run Code Online (Sandbox Code Playgroud)

您可以想到的其他一些用例.

Dan*_*Tao 19

更新:我将利用我的精神力量来试图找出我认为你想要做的事情.

我猜你有一个静态类,你想从另一个类中访问一些方法.是对的吗?

这样的东西,换句话说:

static class HelperMethods
{
    public static void SomeHelperMethod();
}
Run Code Online (Sandbox Code Playgroud)

......你想做的是这样的事情?

class SomeOtherClass
{
    public void MethodThatUsesHelperMethod()
    {
        // You want to be able to have "Helper" mean "HelperMethods"?
        Helper.SomeHelperMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我正确地解释你的,只有一个方法(我能想到的)来排序的完成你以后.这将添加一个using声明来有效地为您的静态类型设置别名:

// At top of file
using Helper = HelperMethods;
Run Code Online (Sandbox Code Playgroud)

请注意,如果执行此操作,则表示您正在创建文件范围的别名.没有办法只在类级别别名.


StaticClass是类的名称.您的StaticProperty属性需要该类的实例,因为该类是实例,所以该实例永远不会存在static.

我真的很惊讶你甚至可以将一个属性类型化为静态类,因为它代表了完全不可能.(哦,等一下,你不能做到这一点,这就是你说的话.)

你说你想存储一个"静态类的引用"; 我必须假设你想要一个对代表该类的Type对象的引用,在这种情况下你应该这样做:

public Type StaticProperty { get; set; }

// ...

StaticProperty = typeof(StaticClass);
Run Code Online (Sandbox Code Playgroud)


Jor*_*dão 7

静态类既抽象密封(看一下生成的IL).因此,您无法创建它的实例,也无法将其子类化为具有子类的实例.仅凭这种组合使您无法获得对静态类实例的引用.

现在,要以您想要的方式引用静态类,您必须在C#中使用元类,或者使用某种不同的别名.

要实现您今天所需的目标,您必须手动将所有方法从包装类委托给所需的静态类,或者放弃静态类型并使用dynamic:

public class StaticWrapper : DynamicObject {
  Type _type;
  public StaticWrapper(Type type) {
    _type = type;
  }
  public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
    var method = _type.GetMethod(binder.Name, BindingFlags.Static | BindingFlags.Public, null, args.Select(a => a.GetType()).ToArray(), null);
    if (method == null) return base.TryInvokeMember(binder, args, out result);
    result = method.Invoke(null, args);
    return true;
  }
  // also do properties ...
}
Run Code Online (Sandbox Code Playgroud)

用法:

public static class GenericStuff {
  public readonly dynamic LinearAlgebra = new StaticWrapper(typeof(LinearAlgebra));
  public readonly dynamic String = new StaticWrapper(typeof(StringUtilities));
  public readonly dynamic Geometry = new StaticWrapper(typeof(GeometryOps));
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你的创造性答案! (2认同)

R. *_*des 5

C#规范的第§8.7.12节内容如下:

不打算实例化的类,只包含静态成员的类应声明为静态类.这类的例子是System.ConsoleSystem.Environment.静态类是隐式密封的,没有实例构造函数.静态类只能与typeof运算符一起使用,并且可以访问类的元素.特别是,静态类不能用作变量的类型或用作类型参数

因为静态类没有构造函数,所以无法实例化它.因为它是密封的,所以不能将其子类化并创建子类的实例.即使你可以继承它,你也无法调用基础构造函数,因此你仍然无法实例化它.

由于无法创建静态类类型的对象,因此将其用作返回类型是没有意义的.

由于StaticClass类型名称而不是表达式,因此不能将其作为参数传递(在您的情况下,传递给属性设置器).但是,您可以获取使用表达式表示它的Type类的实例typeof(StaticClass).