2016-04-23 43 views
0

我有一个类,其存储在继承一个dictionary.I一个“项”类有几个从彼此继承的类物品,解析和存储类

实施例:

Item <- Commodity <- Weapon

这些类只是容器,它们没有特定的方法而只有构造函数,它们只保存信息。

在ItemManager类中我有一个方法获取传递的字符串表示文本文件的名称(没有格式)。通过使用这种格式,我还知道通过给该方法分割线作为数组来调用哪种方法来将该文件中的一行解析为类实例。

我该如何使它在那些处理项目的方法中不需要编写重复的字段分配?

实施例:

在从阵列我有tmpItem.id=int.parse(line[0])和在生成的武器我有tmpWeapon.id = int.parse(line[0])的方法生成的项目的方法。

我做错了吗?如何有效地将一行文本解析为知道继承关系的对象(考虑调用基础构造函数的构造函数)。

+0

为包含不同类型(如武器)的物品生成类。你可以使用结构,但结构已经过时了。 – jdweng

+0

我已经有了,那不是我需要:) –

+0

是的,你确实需要它。它是您声明id属性的基类的项目的基类,那么您不必在继承的类中再次声明它。在继承的类中,您可以使用项目类中的任何项目。 – jdweng

回答

0

创建建设者采取splited进行文件内容,并调用基类的构造。

public class Base 
{ 
    public const int LinesCount = 1; 
    public Item(string[] lines) 
    { 
     Id = int.Parse(lines[0]); 
    } 

    public int Id { get; } 
} 

public class Inherited : Base 
{ 
    public Inherited(string[] lines) : base(lines) 
    { 
     int index = base.LinesCount; 
     OtherProperty = int.Parse(lines[index++]); 
    } 

    public int OtherProperty { get; } 
} 

编辑 为改变每班级行数而增加的解决方案

+0

我想到了这一点,但一个问题是,我将不得不知道调用基类后的索引。假设我有32行的东西,我只需要13行用于基类,然后剩余的用于我的当前类。如果我改变了基类中的某些内容以需要16行,我将不得不更新硬编码的13到16,并且存在忘记这样做的风险:D –

+0

@Rareş:您可以传递额外的偏移量参数,或者传递只有其余的字符串。尽管如此,我不会使用构造函数 - 单独的解析方法也可以工作,而不需要将您的类绑定到任何特定的输入格式:“ParseWeapon”会调用ParseCommodity,而ParseCommodity又会调用ParseItem,正在构建下一个方法的项目以及该方法所需的线条。 –

0

它很好,你意识到你正在复制解析代码并想修复它。

如果所有类都继承自Item类,那么将公共属性移入此类并从此处解析它。例如。

public abstract class Item 
{ 
    public int id { get; set; } 

    public virtual void ParseId(string line) 
    { 
    id = int.Parse(line); 
    } 
} 

现在所有的继承类将具有相同的解析方法,他们可以使用它,但这种方式可以删除重复。

这是我想到的一个最简单的例子。我想接下来你想有一个方法可以解析所有东西并设置这些属性,但我不知道你的策略是什么。但请记住,如果您想删除重复,那么最简单的方法就是将该代码移到基类中(虽然它总是不是最好的情况,但我认为您此时不需要担心)。

已更新:读您的评论之后,我改变了代码下面它可以帮助你的东西

public abstract class Item 
{ 
    public int id { get; set; } 
    public string name { get; set; } 
    public float volume { get; set; } 
    public float minPrice { get; set; } 
    public float mass { get; set; } 
    public string description { get; set; } 

    public virtual void Parse(string[] entries) 
    { 
     int i = 0; 
     id = int.Parse(entries[ i++ ]); 
     name = entries[ i++ ]; 
     minPrice = float.Parse(entries[ i++ ]); 
     volume = float.Parse(entries[ i++ ]); 
     mass = float.Parse(entries[ i++ ]); 
     description = RemoveTabs(entries[ i ]); 
    } 

    public string RemoveTabs(string line) { throw new NotImplementedException(); } 
} 

public class Commodity : Item 
{ 
} 

public class Weapon : Commodity 
{ 
} 

public class CommodityC : Item 
{ 
} 


public class ItemManager 
{ 

    private Item ProcessCommodity(string[] entries) 
    { 
     var commodity = new Commodity(); 
     var weapon = new Weapon(); 

     commodity.Parse(entries); 
     //weapon.Parse(entries); 
     return commodity; 
    } 
} 
+1

只是想知道这里,如果你不使用虚拟方法或未实现的方法 – Needham

+1

优点,这是一个抽象类是什么点。我猜@Rares知道如果“Item”类将被实例化,或者这个方法会在子类中被覆盖,但我会修改我的代码以使其具有虚拟方法。 – adeel41

+0

私人CommodityC ProcessCommodity(字符串[]条目) { CommodityC tmpCommodity = new CommodityC(); int i = 0; tmpCommodity.id = int.Parse(entries [i ++]); tmpCommodity.name = entries [i ++]; tmpCommodity.minPrice = float.Parse(entries [i ++]); tmpCommodity.volume = float.Parse(entries [i ++]); tmpCommodity.mass = float.Parse(entries [i ++]); tmpCommodity.description = RemoveTabs(entries [i]); return tmpCommodity; } –