【问题标题】:static variables are they class-instance variables?静态变量是类实例变量吗?
【发布时间】:2012-05-24 08:57:42
【问题描述】:

简单的问题:

静态变量是class instance variable 还是class variable 基数?

知道class instance variable 是为定义它的每个类和子类定义的变量。 class variable 是对所有定义它的子类(包括它自己)都是全局的变量。

编辑:知道我让很多 C#-ish 家伙窒息,我使用术语类实例,就好像一个类是某个 MetaClass 的实例一样。这大大简化了我的问题。虽然如果你认为 VM 肯定有一个代表 evrey 类的工件(包含方法字典、实例大小、超类......),这并不是完全错误的。 谢谢

【问题讨论】:

    标签: c# variables static


    【解决方案1】:

    静态变量“属于”该类型 - 它们不是实例变量。

    也就是说,它们在类型的所有个实例之间共享,包括generic封闭构造类型。

    例外是用ThreadStatic 修饰的静态变量,使变量在线程中唯一。

    【讨论】:

    • 值得注意的是,泛型将意味着静态属于具有泛型参数的类型。
    • @AdamHouldsworth - 是的。在泛型类型上定义的静态将在closed constructed generic type 的实例之间共享。
    • unclear downvote,顺便说一下,可能更正确的说法是:“静态属于一种类型”。
    • @KamilLach - 只要它们没有被装饰成ThreadStatic
    • @Oded 它们可能是类的实例变量。查看我的编辑
    【解决方案2】:

    静态变量的作用域是为给定的AppDomain 定义它们的类型。它们也可以跨线程共享,除非您使用 ThreadStaticAttribute,此时它们将成为 per 线程。

    类成员显然只限于类的一个实例,但对于派生类来说不是“全局的”。根据访问修饰符,该成员也可能对派生实例可见。

    具有泛型参数的类对于每个封闭的泛型类型都有一个静态变量:

    class MyClass<T>
    {
       public static string Name;
    }
    

    所以MyClass&lt;int&gt; 将拥有自己的Name 副本,而MyClass&lt;string&gt; 将拥有不同的副本。


    看看您选择的答案,您似乎希望每个派生类都有一个静态变量?

    你可以作弊并使用上面的泛型规则:

    class Program
    {
        static void Main(string[] args)
        {
            Derived1.WhatClassAmI = "Derived1";
            Derived2.WhatClassAmI = "Derived2";
    
            Console.WriteLine(Derived1.WhatClassAmI); // "Derived1"
            Console.WriteLine(Derived2.WhatClassAmI); // "Derived2"
    
            Console.WriteLine(BaseClass<Derived1>.WhatClassAmI); // "Derived1"
            Console.WriteLine(BaseClass<Derived2>.WhatClassAmI); // "Derived2"
            Console.Read();
        }
    
        class BaseClass<T> where T : BaseClass<T>
        {
            public static string WhatClassAmI = "BaseClass";
        }
    
        class Derived1 : BaseClass<Derived1>
        {
        }
    
        class Derived2 : BaseClass<Derived2>
        {
        }
    }
    

    它们使用“相同”的静态,但由于类型闭包,每个都有自己的值。

    【讨论】:

    • 很高兴知道,无论如何这是完美的逻辑,因为具有不同类型参数的泛型类的每个实例都会产生具有不同类型的对象。
    • 有趣的解决方案,虽然我不太喜欢它,因为它不是很明显发生了什么。我不想让那个将在我身后维护我的代码的人感到困惑。所以我决定添加一个抽象属性并在每个子类中“重新定义”一个静态变量。
    • @mathk 我个人从不建议实际使用此解决方案,这是一种巨大的代码气味。如果我知道您想要实现什么,我可以提供更合适的解决方案,但就目前而言,您的问题都不是很清楚。
    【解决方案3】:

    它们是类变量。 在 C# 中没有什么比 Smalltalk 类实例变量更好的了。 IE。没有办法定义一个在类的所有实例中通用的变量,但它的子类具有不同的值。

    为了获得“类似”的行为,但缺点是类实例 var 只能在创建类的实例后才能访问,我做了这样的事情:

    public class BaseClass
    {
        private static Dictionary<Type, object> ClassInstVarsDict = new Dictionary<Type, object>();
    
        public object ClassInstVar
        {
            get
            {
                object result;
                if (ClassInstVarsDict.TryGetValue(this.GetType(), out result))
                    return result;
                else
                    return null;
            }
            set
            {
                ClassInstVarsDict[this.GetType()] = value;
            }
        }
    }
    
    public class DerivedClass1 : BaseClass
    {
    }
    
    public class DerivedClass2 : BaseClass
    {
    }
    

    【讨论】:

    • 感谢您的建议。还有一个缺点,就是 ClassInstVar 只能是实例侧属性。它不能是类方面(“aka kindof static”)
    • @mathk 现在我可能会明白你想要什么,我已经用替代方法修改了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2019-03-28
    • 2021-09-14
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多