XLINQ - 是否可以在查询中包含条件?

时间:2010-08-17 20:27:38

标签: asp.net linq-to-xml conditional

在尝试自学ASP.NET和OO设计时,我决定制作一个简单的基于网络的游戏。这是一个基本的角色扮演游戏,玩家可以创造某个职业的角色。这些职业赋予角色某些类型的攻击,其中一些技能具有状态效果(对敌人有毒,对角色有防御性增益等)。

专业数据存储在XML文件中。我认为这将是使其在未来可扩展的最佳方式。如果我(或其他任何人)想要添加/更改专业,他们需要做的就是编辑或添加XML文件。

所以,尽管如此,我一直在测试如何成功地从我的专业XML文件中提取各种攻击。就像我之前说的那样,它们中的一些具有状态效果,但不是全部。以下是测试专业:

<?xml version="1.0" encoding="utf-8" ?>
<CharacterClass>
  <Name>Hacker</Name>
  <InitialStats>
    <HP>10</HP>
    <TP>25</TP>
    <BaseDMG>2</BaseDMG>
    <BaseDefense>25</BaseDefense>
  </InitialStats>
  <LevelingStats>
    <HPMultiplier>2</HPMultiplier>
    <TPMultiplier>4</TPMultiplier>
    <BaseDMGMultiplier>2</BaseDMGMultiplier>
    <DefenseIncrease>5</DefenseIncrease>
  </LevelingStats>
  <Attacks>
    <Attack>
      <AttackName>Basic Attack</AttackName>
      <AttackLevel>1</AttackLevel>
      <TPCost>0</TPCost>
      <DMGModifier>1</DMGModifier>
      <HitPenalty>0</HitPenalty>
      <StatusEffect>
        <Type>null</Type>
        <Duration>0</Duration>
        <Level>0</Level>
      </StatusEffect>
    </Attack>
  </Attacks>
</CharacterClass>

正如您所看到的,每个职业都会发出各种攻击,这些攻击是我系统中的对象。状态效果也是对象 - 事实上,它们是可以附加到角色的观察者。

我的问题源于没有状态影响的攻击,例如上面显示的基本攻击。我有一个部分解决方案,但它似乎不优雅:

public partial class xmltest : System.Web.UI.Page
{
    public StatusEffect CreateStatusEffect(XElement se)
    {
        if (se.Element("Type") != null)
        {
            StatusEffect result = (StatusEffect)Assembly.GetExecutingAssembly().CreateInstance(((string)se.Element("Type")));
            result.Name = (string)se.Element("Name");
            result.Duration = (int)se.Element("Duration");
            result.Level = (int)se.Element("Level");

            return result;
        }
        else
        {
            throw new Exception();
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        List<Attack> charAttacks = (from a in XElement.Load(MapPath("CharacterClasses/Hacker.xml")).Element("Attacks").Elements("Attack")
                                    let se = a.Element("StatusEffect")
                                    select new Attack
                                    (
                                        (string)a.Element("AttackName"),
                                        (int)a.Element("AttackLevel"),
                                        (int)a.Element("TPCost"),
                                        (double)a.Element("DMGModifier"),
                                        (double)a.Element("HitPenalty"),
                                        CreateStatusEffect(se)
                                    )).ToList();


        foreach (Attack attack in charAttacks)
        {
            output.InnerHtml = attack.Name + "<br />";
        }
    }
}

我可以:

  1. 检查是否存在状态效果
  2. 如果存在则构建
  3. 在LINQ查询本身内?使用当前正在执行的程序集注册为我的代码异味。我确定我错过了一些明显的东西。

1 个答案:

答案 0 :(得分:1)

试试这个

XDocument doc = XDocument.Load( MapPath("CharacterClasses/Hacker.xml"));   
List<Attack> charAttacks = (from attack in doc.Descendants("Attack")
                                    select new Attack()
                                    {
                                        AttackName = (string)attack.Element("AttackName") ?? null,
                                        AttackLevel = (int)attack.Element("AttackLevel"),
                                        TPCost = (int)attack.Element("TPCost"),
                                        DMGModifier = (double)attack.Element("DMGModifier"),
                                        HitPenalty = (double)attack.Element("HitPenalty"),
                                        StatusEffect = attack.Element("StatusEffect") == null ? null :
                                                              new StatusEffect()
                                                              {
                                                                  Name = (string)attack.Element("StatusEffect").Element("Name"),
                                                                  Duration = (int)attack.Element("StatusEffect").Element("Duration"),
                                                                  Level = (int)attack.Element("StatusEffect").Element("Level")
                                                              }
                                    }).ToList();`enter code here`

Attack和StatusEffect的类定义需要具有如下所示的公共属性,以使上述linq语句生效

class Attack
    {
        public string AttackName { get; set; }
        public int AttackLevel { get; set; }
        public int TPCost { get; set; }
        public double DMGModifier { get; set; }
        public double HitPenalty { get; set; }
        public StatusEffect StatusEffect { get; set; }
    }

    class StatusEffect
    {
        public string Name { get; set; }
        public int Duration { get; set; }
        public int Level { get; set; }
    }