如何,从静态方法;访问静态方法中使用的静态属性的唯一值
本文关键字:静态方法 静态 属性 唯一 访问 如何 | 更新日期: 2023-09-27 18:14:31
我想在同一线程上运行的其他静态方法中访问static字段的值。下面的代码中有一个例子:
这个脚本中的第一个类是ClassA
。ClassA的工作是比较两个Rect
值,如果两个比较的Rect
值之间不相等,则公共布尔值设置为true;
在类a中,IsRectChanged
是一个布尔方法,它接受类型为Rect
的参数对象,并将其与Rect
的StoredRect
进行比较。当storedRect
和IsRectChanged
的Rect
值不匹配时,该方法返回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
中创建了一个名为isRectChanged
的ClassA
静态字段。不要更改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");
}
}
}
ClassC
、ClassD
和ClassE
在同一线程上运行。它们都调用ClassB.MethodB
,并在MethodB
的参数中分配一个new Rect
。
因为ClassC
、ClassD
和ClassE
被调用为ClassB.MethodB
,并且在MethodB
的参数中分配一个new Rect
。它们各自覆盖静态字段ClassA RectHelper
的storedRect
值。
因此,ClassA
RectHelper.IsRectChanged
将始终为真。
如何在不必使ClassB
的ClassA
和ClassE
的MethodB
非静态的情况下解决此问题?**
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,所以每当类ClassC
、ClassD
和ClassE调用MethodB
时,它们都会共享该值。但是我们能解决这个问题吗?这样ClassC
和ClassD
就不会覆盖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 通过将ClassB制作为模板,每个ClassB<>是一个不同的静态对象,每个对象都有自己的静态变量副本。现在,除了对ClassC和ClassD的第一个调用外,以下代码将对所有调用返回false。 以下是课程。。。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(...));
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));
}
}