如何,从静态方法;访问静态方法中使用的静态属性的唯一值

本文关键字:静态方法 静态 属性 唯一 访问 如何 | 更新日期: 2023-09-27 18:14:31

我想在同一线程上运行的其他静态方法中访问static字段的值。下面的代码中有一个例子:

这个脚本中的第一个类是ClassA。ClassA的工作是比较两个Rect值,如果两个比较的Rect值之间不相等,则公共布尔值设置为true;

在类a中,IsRectChanged是一个布尔方法,它接受类型为Rect的参数对象,并将其与RectStoredRect进行比较。当storedRectIsRectChangedRect值不匹配时,该方法返回true。

    public class ClassA
    {
        private Rect storedRect;
        public ClassA() { }
        public bool IsRectChanged(Rect rect)
        {
            bool isChanged = !rect.Equals(storedRect);
            if(isChanged)
            {
                storedRect = rect;
            }
            return isChanged;
        }
    }

这是ClassB我们在ClassB中创建了一个名为isRectChangedClassA静态字段。不要更改ClassB中MethodB的结构。考虑以下事实:静态和非静态类中的50个其他方法必须使用ClassA字段。需要更改ClassB的结构以使代码正常工作会适得其反。

    public static class ClassB
    {
        private static ClassA RectHelper = new ClassA();
        public static void MethodB(Rect yourRect)
        {
           if(RectHelper.IsRectChanged(yourRect))
           {
               Debug.Log("Changes were made");
           }
        }
    }

ClassCClassDClassE在同一线程上运行。它们都调用ClassB.MethodB,并在MethodB的参数中分配一个new Rect

因为ClassCClassDClassE被调用为ClassB.MethodB,并且在MethodB的参数中分配一个new Rect。它们各自覆盖静态字段ClassA RectHelperstoredRect值。

因此,ClassARectHelper.IsRectChanged将始终为真。

如何在不必使ClassBClassAClassEMethodB非静态的情况下解决此问题?**

    public class ClassC
    {
        public void UpdateEverFrame()
        {
            ClassB.MethodB(new Rect(0, 0, 20, 20));
        }
    }
    public class ClassD
    {
        public void UpdateEverFrame()
        {
            ClassB.MethodB(new Rect(100, 100, 10, 10));
        }
    }

ClassE中,ClassB.MthodB在两个UpdateEverFrame方法中被调用,其中一个方法接受int参数。如果同时调用它们,则它们会相互覆盖,因此系统将相信IsRectChanged为true,并且始终返回true。这是一个大问题。

我们不希望IsRectChanged被覆盖,我们希望ClassB.MethodB的每个调用都被视为不是静态的,这样IsRectChanged就永远不会被覆盖

    public class ClassE
    {
        public void UpdateEverFrame()
        {
            ClassB.MethodB(new Rect(0, 0, 20, 20));
        }
        public void UpdateEverFrame(int i)
        {
            ClassB.MethodB(new Rect(100, 100, 10, 10));
        }
    }

在我的问题中,当我说"访问静态属性的唯一值"时,我指的是ClassB.RectHelper

我知道ClassB.RectHelper是STATIC,所以每当类ClassCClassD和ClassE调用MethodB时,它们都会共享该值。但是我们能解决这个问题吗?这样ClassCClassD就不会覆盖ClassA中的storedRect值?

如何,从静态方法;访问静态方法中使用的静态属性的唯一值

为什么不跳过静态类B,在类C和D中创建类a的静态属性呢?你构建代码的方式对我来说似乎很糟糕

public class ClassA
{
    protected Rect storedRect;
    public ClassA() { }
    public virtual void UpdateEverFrame();
    protected bool IsRectChanged(Rect rect)
    {
        bool isChanged = !rect.Equals(StoredRect);
        if(isChanged)
        {
            storedRect = rect;
        }
        return isChanged;
    }
}
public class ClassC : ClassA
{
    public override void UpdateEverFrame()
    {
        if(IsRectChanged(new Rect(0, 0, 20, 20)))
        {
             Debug.Log("Changes were made class C");
        }
    }
}
public class ClassD : ClassA
{
    public override void UpdateEverFrame()
    {
        if(IsRectChanged(new Rect(100, 100, 10, 10)))
        {
             Debug.Log("Changes were made class D");
        }
    }
}

我不明白目的,但你想过让ClassB通用吗?类似的东西:

    public class ClassB<T>
    {
        private static ClassA if_rect_Changed = new ClassA();
        public static void MethodB(Rect yourRect)
        {
            if (if_rect_Changed.RectChanged(yourRect))
            {
                Debug.Log("Changes were made");
            }
        }
    }

像这样使用它:ClassB<ClassC>.MethodB(rect),这样每个类都会有它的"更改跟踪器"的"副本",并且您将能够保持MethodB静态。

首先进行一些澄清。我假设您使用的是System。Windows。Rect,对吗?更多澄清。。。

我们在ClassB中有一个名为isRectChanged的ClassA静态属性

不,您在ClassB中有一个ClassA类型的静态字段,名为RectHelperIsRectChanged是ClassA的一个非静态方法。

我们希望在同一线程上运行的其他静态方法中访问static属性的值。

由于它们在同一个线程上,因此您的静态方法不可能同时被调用。到目前为止,没有问题。

他们都称为ClassB。方法B并覆盖方法B的Rect参数的值。两个类都使用相同的ClassB.MethodB实例。。。

它们不覆盖Rect参数,而是各自提供一个Rect对象ClassB是实例,而不是ClassB.MethodB

永远都是真的。

事实并非如此,请尝试运行下面的代码,您将看到只有第一个调用返回true

ClassC c = new ClassC();
c.UpdateEverFrame();
c.UpdateEverFrame();
c.UpdateEverFrame();

但是,如果在两行之间插入通过ClassD的调用,是的,IsRectChanged将返回true,因为这是真的,Rect实际上是不同的。但是,这就是static的作用,也就是说,它适用于Singleton类型的操作。

如果每个类都想要一个静态变量,那么在每个类中放入一个静态变量。如果需要重复代码,请使用模板。例如,它不必太花哨,只需更改ClassB和对ClassB

public class ClassB<TClass> // the rest of the class is the same
...
/* in ClassC */ ClassB<ClassC>.MethodB(new Rect(...));
...
/* in ClassD */ ClassB<ClassD>.MethodB(new Rect(...));

通过将ClassB制作为模板,每个ClassB<>是一个不同的静态对象,每个对象都有自己的静态变量副本。现在,除了对ClassCClassD的第一个调用外,以下代码将对所有调用返回false

        ClassC c = new ClassC();
        c.UpdateEverFrame();
        c.UpdateEverFrame();
        c.UpdateEverFrame();
        ClassD d = new ClassD();
        d.UpdateEverFrame();
        d.UpdateEverFrame();
        c.UpdateEverFrame();
        d.UpdateEverFrame();

以下是课程。。。

public static class ClassB<TClass>
{
    private static ClassA RectHelper = new ClassA();
    public static void MethodB(Rect yourRect)
    {
        if (RectHelper.IsRectChanged(yourRect))
        {
            Debug.WriteLine("Changes were made");
        }
    }
}
public class ClassC
{
    public void UpdateEverFrame()
    {
        ClassB<ClassC>.MethodB(new Rect(0, 0, 20, 20));
    }
}
public class ClassD
{
    public void UpdateEverFrame()
    {
        ClassB<ClassD>.MethodB(new Rect(100, 100, 10, 10));
    }
}