类似于:
public static class StaticClass {}
public class InstanceClass
{
static StaticClass StaticProperty {get;set;}
public InstanceClass()
{
InstanceClass.StaticProperty = StaticClass;
}
}
我认为可以做到这一点,但编译器会返回这些错误:
编辑:我知道这不起作用,但为什么呢?我想StaticClass存储在内存中的某个地方,所以可以允许其他变量在同一个内存中引用它,对吗?静态类型不能用作参数
静态类型不能用作返回类型
EDIT2:其中一个用例是这样的:
假设您收集了5个不同的静态类而没有源代码,并且它们执行通用的东西,因此您希望通过单个静态类方便地访问它们。你可以这样做:
public static class GenericStuff
{
public LinearAlgebra LinearAlgebra {get;set;}
public StringUtilities String {get;set;}
public GeometryOps Geometry {get;set;}
}
并使用它:
GenericStuff.LinearAlgebra.GetAngleBetweenVectors(v0, v1);
您可以想到的其他一些用例。
答案 0 :(得分:18)
更新:我将利用我的心灵力量来尝试计算我认为你尝试做什么。
我猜你有一个静态类,你想从另一个类中访问一些方法。是吗?
这样的东西,换句话说:
static class HelperMethods
{
public static void SomeHelperMethod();
}
......你想做的是这样的事情吗?
class SomeOtherClass
{
public void MethodThatUsesHelperMethod()
{
// You want to be able to have "Helper" mean "HelperMethods"?
Helper.SomeHelperMethod();
}
}
如果我已经正确地解释了你,只有一种方式(我能想到)那种完成你所追求的目标。这将是添加using
声明以有效地为您的静态类型设置别名:
// At top of file
using Helper = HelperMethods;
请注意,如果执行此操作,则表示您正在创建文件范围的别名。没有办法只在类级别别名。
StaticClass
是该类的名称。您的StaticProperty
属性需要该类的实例,该类将永远不存在,因为该类为static
。
我真的很惊讶你甚至可以把一个属性输入为静态类,因为它代表了一种完全不可能。(哦等等,你不能做那就是你所说的。)
你说你想存储一个“静态类的引用”;我必须假设你想要引用代表类的Type
对象,在这种情况下你应该这样做:
public Type StaticProperty { get; set; }
// ...
StaticProperty = typeof(StaticClass);
答案 1 :(得分:7)
静态类都是抽象和密封(看一下生成的IL)。因此,您无法创建它的实例,也无法将其子类化为具有子类的实例。仅凭这种组合使您无法获得对静态类实例的引用。
现在,要以您想要的方式引用静态类,您必须在C#中使用metaclasses,或者使用某种不同的别名。
要实现您今天所需的目标,您必须手动将所有方法从包装类委托给所需的静态类,或者放弃静态类型并使用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 ...
}
用法:
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));
}
答案 2 :(得分:5)
C#规范的§8.7.12部分为:
不打算成为的类 实例化,仅包含 静态成员应声明为 静态类。这样的例子 课程是
System.Console
和System.Environment
。静态类 是隐含的密封,没有 实例构造函数。静态类 只能与typeof一起使用 运算符和访问元素 类。特别是一个静态类 不能用作a的类型 变量或用作类型参数
因为静态类没有构造函数,所以无法实例化它。因为它是密封的,所以不能将其子类化并创建子类的实例。即使你可以继承它,你也无法调用基础构造函数,因此你仍然无法实例化它。
由于无法创建静态类类型的对象,因此将其用作返回类型是没有意义的。
由于StaticClass
是type name,而不是expression,因此您无法将其作为参数(在您的情况下,传递给属性设置器)传递。但是,您可以使用表达式typeof(StaticClass)
获取表示它的Type类的实例。
答案 3 :(得分:3)
您无法存储对静态类的引用。您只能存储对实例的引用,并且没有静态类的实例(尽管静态类可能包含实例成员)。
答案 4 :(得分:1)
答案 5 :(得分:1)
我认为这就是你想说的:
好的,如果您不想实例化它,那么您的C#需要更多调整。假设您的静态类实现了属性和/或方法
public static class StaticClass
{
public static string StaticProperty {get; private set; }
public static void StaticMethod() { //DoSomething }
}
您可以在InstanceClass中转发属性和函数定义,请注意您必须将static的类名前缀添加到要调用的方法/属性中。
public class InstanceClass
{
private string StaticProperty
{
get { return StaticClass.StaticProperty; }
}
private StaticMethod()
{
StaticClass.StaticMethod();
}
public InstanceClass()
{ }
}
我认为使用InstanceClass作为这样的包装器有点复杂,而且不必要。我发现值得尝试最小化代码库中对静态类和方法的需求。在尝试测试和调试时,它们会引起各种各样的麻烦。
答案 6 :(得分:0)
你不能这样做。一个类不是它自己的一个实例。 “狗”不是狗。您可以将typeof(StaticClass)
分配给Type:
static StaticClass StaticProperty {get; set}
InstanceClass.StaticProperty = typeof(StaticClass);
这使您可以对类型使用反射。
答案 7 :(得分:0)
我认为操作系统想要的是一种通过"代理"轻松访问其他课程的方法。你知道的。
所以,假设您有一个名为MapHelpers的类:
public class MapHelper
{
public static string CalculateNearLocation (Vector3 position){...}
}
你还有很多其他的帮助"你真的不记得,只是想让它们易于访问。所以,你想要"存储"他们在你的"助手"上课,这样你才能记住你把它们放在哪里。
你可以这样做:
public class Helpers
{
public class MapHelpers : MapHelper{}
}
并且可以通过以下方式访问您的MapHelper:
Helpers.MapHelpers.CalculateNearLocation(pos)
或者这样做:
public partial class Helpers
{
}
public partial class Helpers
{
public class MapHelper
{
public static string CalculateNearLocation (Vector3 position){...}
}
}
并且可以通过以下方式访问它:
Helpers.MapHelper.CalculateNearLocation(pos)
但是,第一种方法会在IDE上给出一个警告(如果你有那套),关于通过派生类型访问静态方法。
答案 8 :(得分:0)
我相信使用命名空间功能将是完成您尝试的最佳方式。
LinearAlgebra.cs
namespace GenericStuff
{
public static class LinearAlgebra
{
public static TypeOfResult Function() { ... }
}
}
Strings.cs
namespace GenericStuff
{
public static class Strings
{
public static TypeOfResult Function() { ... }
}
}
Geometry.cs
namespace GenericStuff
{
public static class Geometry
{
public static TypeOfResult Function() { ... }
}
}
所有这些都可以从GenericStuff
开始调用var s = GenericStuff.Strings.Random(7);
var identity = GenericStuff.LinearAlgebra.Identity(3);
var square = GenericStuff.Geometry.Square(5);
var area = square.Area();