C# 如何使用继承为类缓存静态数据?
假设您正在制作一个使用某种纹理的游戏对象:C# 如何使用继承为类缓存静态数据?,c#,unity3d,C#,Unity3d,假设您正在制作一个使用某种纹理的游戏对象: public class Action { //This two can (must) be overriden public const string _HoverCursor = "Textures/cursors/select"; public virtual string HoverCursor { get { return _HoverCursor; } } //This is the get texture
public class Action {
//This two can (must) be overriden
public const string _HoverCursor = "Textures/cursors/select";
public virtual string HoverCursor { get { return _HoverCursor; } }
//This is the get texture by string
private static Texture2D cursorTex = null;
public static Texture2D cursor { get { return ResourceManager.loadTexture(ref cursorTex, HoverCursor); } }
}
如果传递了null
,则loadTexture
函数将加载纹理。否则,它只返回原始值
如你所见,我正在制作一个动作原型。会有攻击、移动或建造等动作。我希望每个类定义存储一个(和不同的)纹理对象。该对象应使用上述getter
由于,如何为所有子实例实现此功能
以下是loadTexture
:
public static Texture2D loadTexture(ref Texture2D target, string name)
{
if (target == null)
{
target = (Texture2D)Resources.Load(name, typeof(Texture2D));
}
return target;
}
您可以对实例成员使用继承和多态性,并使用静态工厂方法作为外观来简化实现的实例化 比如说
public abstract class Action
{
public abstract void LoadTexture(...);
}
// Since static façade class has a generic type parameter, we're talking
// about a completely different class than just "Action" and both can co-exist!
public static class Action<TAction> where TAction : Action, new()
{
public static Texture2D LoadTexture(...)
{
// Since generic TAction parameter must implement a public parameterless
// constructor, you may instantiate T like a concrete class:
return new TAction().LoadTexture(...);
}
}
公共抽象集体诉讼
{
公共抽象结构(…);
}
//因为静态façade类有一个泛型类型参数,所以我们现在讨论
//关于一个完全不同于“行动”的类,两者可以共存!
公共静态集体诉讼,其中战术:行动,新()
{
公共静态纹理2D LoadTexture(…)
{
//由于泛型TAction参数必须实现公共无参数
//构造函数,您可以像实例化具体类一样实例化T:
返回新的TAction().LoadTexture(…);
}
}
因此,您将使用静态方法,如下所示:
Texture2D texture = Action<CustomAction>.LoadTexture2D(...);
Texture2D texture=Action.LoadTexture2D(…);
你自己实际上已经回答了这个问题:
由于静态属性不能被重写,我如何为所有子实例实现这一点
只需将该属性设置为实例属性。例如:
public class Action {
//This two can (must) be overriden
public const string _HoverCursor = "Textures/cursors/select";
public virtual string HoverCursor { get { return _HoverCursor; } }
//This is the get texture by string
private static Texture2D cursorTex = null;
public virtual Texture2D cursor
{
get
{
return ResourceManager.loadTexture(ref cursorTex, HoverCursor);
}
}
}
public class Attack {
//This two can (must) be overriden
public const string _HoverCursor = "Textures/cursors/attack";
public virtual string HoverCursor { get { return _HoverCursor; } }
//This is the get texture by string
private static Texture2D cursorTex = null;
public override Texture2D cursor
{
get
{
return ResourceManager.loadTexture(ref cursorTex, HoverCursor);
}
}
}
//This is the get texture by string
private static Lazy<Texture2D> cursorTex =
new Lazy<Texture2D>(() => ResourceManager.loadTexture(HoverCursor));
public virtual Texture2D cursor
{
get
{
return cursorTex.Value;
}
}
您仍然可以为每个类只保存一个纹理,但是给定每个类的一个实例,您将能够为该类检索正确的光标纹理。假设您只需要在存在类实例的情况下设置游标,所以这不应该是一个不合理的限制
请注意,如果没有其他代码实际需要HoverCursor
属性,则可以将其删除,将\u HoverCursor
常量设为私有成员,然后直接在cursor
属性获取程序中使用它
还要注意,此实现不是线程安全的。只要始终从单个线程访问游标
属性,就可以了。但是如果不是(或者只是为了简单起见),您可能更喜欢使用Lazy
类。例如:
public class Action {
//This two can (must) be overriden
public const string _HoverCursor = "Textures/cursors/select";
public virtual string HoverCursor { get { return _HoverCursor; } }
//This is the get texture by string
private static Texture2D cursorTex = null;
public virtual Texture2D cursor
{
get
{
return ResourceManager.loadTexture(ref cursorTex, HoverCursor);
}
}
}
public class Attack {
//This two can (must) be overriden
public const string _HoverCursor = "Textures/cursors/attack";
public virtual string HoverCursor { get { return _HoverCursor; } }
//This is the get texture by string
private static Texture2D cursorTex = null;
public override Texture2D cursor
{
get
{
return ResourceManager.loadTexture(ref cursorTex, HoverCursor);
}
}
}
//This is the get texture by string
private static Lazy<Texture2D> cursorTex =
new Lazy<Texture2D>(() => ResourceManager.loadTexture(HoverCursor));
public virtual Texture2D cursor
{
get
{
return cursorTex.Value;
}
}
//这是按字符串获取纹理
私有静态惰性cursorTex=
新的Lazy(()=>ResourceManager.loadTexture(HoverCursor));
公共虚拟纹理2D游标
{
得到
{
返回cursorTex.Value;
}
}
在此版本中,请注意
loadTexture()
方法已更改为始终加载纹理,因此不需要ref
参数。Lazy
类将确保线程安全的延迟初始化,每个类只调用一次loadTexture()
。这确实很酷,但它有效吗?我想用静态数据来保存RAM,但CPU更为重要,尤其是现在的8GB RAM…@TomášZato Yeah。。。嗯,我想你会加载纹理或其他东西,如果在某些场景中不再需要它们,你应该卸载它们。顺便说一句,看看Lazy
@TomášZato我相信它是在.NET4.0中引入的