在base中定义的静态对象对于子类应该是不同的

时间:2014-02-20 16:36:41

标签: c# inheritance static

我有一个基类BaseClass,它有一个纹理或位图。两个类派生自它,比如AChildBChild。每个子类都设置纹理。现在,每个子类的Texture将保持相同。对于每个子类的对象,我不想要多个Texture变量。我希望它是单身人士。

这是一些代码。

abstract class BaseClass
{
    public Texture TextureImage { get; set; }
    public Texture LoadTexture(string path)
    {
         return some texture using path,
    }
}

class AChild : BaseClass
{
    AChild()
    {
         if (TextureImage == null)
             TextureImage = LoadTexture(PathToImageA);
    }
}

class BChild : BaseClass
{
    BChild()
    {
         if (TextureImage == null)
             TextureImage = LoadTexture(PathToImageB);
    }
}

Main()
{
     var aOne = new AChild();
     var aTwo = new AChild();

     var bOne = new BChild();
     var bTwo = new BChild();

}

现在,您可以看到每当我创建AChildBChild的对象时,都会创建一个新纹理。我想要实现的是,每当创建AChild的第一个子(aOne)时,应该初始化TextureImage,并且当创建另一个对象(aTwo)时,它使用由第一个孩子创建的纹理。

我试图在基类中使TextureImage静态,但在那之后bOne纹理是aOne创建的纹理。

我确信这可能是我想要的,但问题是如何?

3 个答案:

答案 0 :(得分:3)

受到 crashmstr 评论和晚安睡眠的启发,我想出了这个解决方案

class Program
{
    static void Main(string[] args)
    {
        AChild a1 = new AChild();
        Console.WriteLine(a1.TextureImage.Path);
        BChild b = new BChild();
        Console.WriteLine(b.TextureImage.Path);
        AChild a2 = new AChild();
        Console.WriteLine(a2.TextureImage.Path);
    }
}

public class Texture
{
    public string Path { get; set; }

}

public abstract class BaseClass
{
    public static ConcurrentDictionary<Type, Texture> TextureImageCache { get; set; }

    static BaseClass()
    {
        TextureImageCache = new ConcurrentDictionary<Type, Texture>();
    }

    public virtual Texture TextureImage
    {
        get
        {
            return TextureImageCache.GetOrAdd(
                this.GetType(),
                t => this.LoadTexture(this.TexturePath));
        }
    }

    public Texture LoadTexture(string path)
    {
        return new Texture { Path = path };
    }

    public abstract string TexturePath { get; }
}

public class AChild : BaseClass
{

    public override string TexturePath
    {
        get { return "iamgeA"; }
    }
}

public class BChild : BaseClass
{

    public override string TexturePath
    {
        get { return "imageB"; }
    }
}

一些亮点:

  • ConcurrentDictionary,仅在首次需要时加载纹理(延迟加载)
  • 基类只使派生类实现Path属性。
  • 我坚信这是一个优雅而强大的解决方案,无需在派生类中直接操作type,并且可以非常轻松地扩展到新的派生类

答案 1 :(得分:0)

我重写了使用抽象属性的答案。在AChild&amp; amp; BChild。

TextureImage BaseClass中设置abstract媒体资源。然后,覆盖AChild&amp;中的抽象属性。 BChild

abstract class BaseClass
{
    public abstract Texture TextureImage { get; }
    private Texture _TextureImage;
}

class AChild : BaseClass
{
    public override Texture TextureImage {
        get {
          if ( _TextureImage == null )
              _TextureImage = LoadTexture(PathToImageA);
          return _TextureImage;
        }
    }
}

class BChild : BaseClass
{
    public override Texture TextureImage {
        get {
          if ( _TextureImage == null )
              _TextureImage = LoadTexture(PathToImageB);
          return _TextureImage;
        }
    }
}

Main()
{
     var aOne = new AChild();
     var aTwo = new AChild();

     var bOne = new BChild();
     var bTwo = new BChild();

}

答案 2 :(得分:0)

这未经过测试,但我认为这会做你想要的。 在每个子类中,使用私有Textureoverride基类TextureImage来使用子类自己的静态版本。

abstract class BaseClass
{
    public static Texture TextureImage { get; set; }
    public Texture LoadTexture(string path)
    {
         //return some texture using path,
    }
}

class AChild : BaseClass
{
    private static Texture TextureImageA { get; set; }
    public override Texture TextureImage 
    {
        get { return TextureImageA; }
        set { TextureImageA = value; }
    }

    AChild()
    {
         if (TextureImage == null)
             TextureImage = LoadTexture(PathToImageA);
    }
}

class BChild : BaseClass
{
    private static Texture TextureImageB { get; set; }
    public override Texture TextureImage 
    {
        get { return TextureImageB; }
        set { TextureImageB = value; }
    }

    BChild()
    {
         if (TextureImage == null)
             TextureImage = LoadTexture(PathToImageB);
    }
}