2017-05-30 68 views
1

我有一个类Item继承成员的新属性

public class Item 
    { 
     public int ID { get; private set; } 
     public int Value { get; private set; } 

     public Item CachedReference 
     { 
      get 
      { 
       return Server.Instance.Data.Items[this.ID]; 
      } 
     } 

     public Item(int id) 
     { 
      this.ID = id; 
      this.Value = this.CachedReference.Value; 
     } 
} 

我有一个类EquipItem派生:

public sealed class Equip : Item 
{ 
    public new Equip CachedReference 
    { 
     get 
     { 
      return Server.Instance.Data.Equips[this.ID]; 
     } 
    } 
} 

public Equip(int id) : base(id) { } 

当我打电话:

Equip equip = new Equip(id); 

Item base的构造函数将使用CachedReference财产Item,而不是新的CachedReference财产Equip。我该如何做到这一点,如果我初始化类型为Equip的对象,基地Item类将使用CachedReferenceEquip而不是Item

+3

通过建立在'Equip'一个新的构造函数调用一个新的,无参数的构造函数基地这什么也不做,或者使用'virtual'和'而是override' 'new'。你有什么尝试? – CodeCaster

+0

@CodeCaster问题是因为'Equip'派生自'Item',它也需要'Value'属性。因此我希望基类能够获得基本的值。 –

+0

@CodeCaster我没有使用虚拟方法,并用'Equip'覆盖它,但我希望'CachedReference'返回'Equip'类型而不是'Item',所以我不必将其转换到我的构造函数中。 –

回答

0

一般,理想的方式来做到这一点自动CachedReference成为virtual方法(或:间接调用一个virtual方法),即Equip覆盖

但是!在这种情况下,你在谈论一个构造函数;您应该在构造函数中调用virtual方法而不是。相反,另一种方法是通过构造函数将期望值向下传递给(为此,它可以是不同的protected构造函数)。

例如:

private static GetCachedReference(int id) 
    => Server.Instance.Data.Items[id]; 
public Item(int id) : (id, GetCachedReference(id).Value) {} 
protected Item(int id, int value) 
{ 
    this.ID = id; 
    this.Value = value; 
} 

private static GetCachedReference(int id) 
    => Server.Instance.Data.Equips[this.ID]; 
public Item CachedReference => GetCachedReference(ID); 
public new Equip CachedReference => GetCachedReference(ID); 
public Equip(int id) : base(id, GetCachedReference(id).Value) { } 
+0

你能告诉我一个例子吗?我不太明白。 –

+0

@GilbertWilliams添加了一个例子,但是有大约6种不同的方式来解决这个问题,包括存储引用本身而不是值,并且在getter中执行.Value –

0

一般而言,我会说,这是一个不好的设计。你的类(Item)一次处理2件事(存储值和缓存)。比方说,稍后想要更改缓存机制(对Redis或某事),这将非常困难。

底线是你应该有一个单独的类/接口来处理缓存。

这是一个(非常)的简化版本

public class Item 
{ 
    public int Id { get; } 

    public Item(int id) 
    { 
     Id = id; 
    } 
} 

public class Equip : Item 
{ 
    public Equip(int id) : base(id) 
    { 
    } 
} 

public class CacheManager 
{ 
    public TItem GetItem<TItem>(int id) where TItem : Item 
    { 
     if (typeof(TItem) == typeof(Equip)) 
     { 
      return Server.Instance.Data.Equips[id]; 
     } 

     return Server.Instance.Data.Items[id]; 
    } 
}