【问题标题】:C# Define (multiple) possible types for property of a classC#为类的属性定义(多个)可能的类型
【发布时间】:2017-01-17 14:03:39
【问题描述】:

我认为我在这里遇到了基本的 OOP 误解:

(顺便说一句,这些是 Entity Framework 6 类,以防您对“虚拟”感到惊讶)

public class WeaponUsed : HistoryEvent
{
    public virtual Player Target { get; set; }
    public virtual GameCountry Country { get; set; }
    //Victims: Troops or Pops
    public ICollection<Victim> Victims { get; set; }
    public bool HasMoreWeaponsLeft { get; set; }
}

受害者可以是“部队”对象或“人口”对象。受害者类别必须是什么样子?我可以使用 2 个属性并将未使用的属性设置为“null”,如下所示:

public class Victim
{
    public virtual Troop TroopVictim { get; set; }
    public virtual Population PopVictim { get; set; }
}

但这不可能是最好的解决方案,对吧? 我想确定受害者可以是要么部队人口。

我也想过通过setter来做:

public ICollection<object> Victims { get; 
    set 
    {
        if (value.GetType() == typeof(Troop) || value.GetType() == typeof(Population))
            Victims.Add(value);
    }
}

但我仍然不认为这是最好的方法,或者它可能是...... 有没有更好、更清洁的?

【问题讨论】:

  • 您可以尝试使用enum,例如:enum Victim { Troop, Population }
  • 我知道,但我需要存储在对象中的额外信息。 “名字”本身是不够的。
  • 您需要存储哪些额外信息?
  • 基类应该是victim。从victim 派生TroopPopulation
  • IMO,这是你能得到的最好的。你也可以试试table per hierarchy mapping

标签: c# entity-framework class oop properties


【解决方案1】:

您可以使用接口。

public class WeaponUsed : HistoryEvent
{
    public virtual Player Target { get; set; }
    public virtual GameCountry Country { get; set; }
    //Victims: Troops or Pops
    public IVictim Victims { get; set; }
    public bool HasMoreWeaponsLeft { get; set; }
}

public interface IVictim {
    // common methods and properties for PopVictim and TroopVictim
    int Number {get;}
}

public class TroopVictim : IVictim {
    // TroopVictim will be enforced to have IVictim methods and proprieties
    public int Number{ get {return 1; } }
} 

public class PopVictim : IVictim {
    // PopVictim will be enforced to have IVictim methods and proprieties
    public int Number{ get {return 100; } }
} 

用法:

 Console.WriteLine(weapon.Victims.Number)

【讨论】:

  • 嗯,我的主要要求是保留相关部队/人口对象的连接/外键。在这里,我只会创建新的,这对我的问题没有帮助。我想我只需要让部队/人口从受害者那里继承……还是我在这里误解了什么?
【解决方案2】:

界面伴侣!

    public interface IVictim
    {
        string SharedProp { get; set; }
    }

    public class TroopVictim : IVictim
    {
        public string SharedProp { get; set; }

        public string TroopProperty { get; set; }
    }

    public class PopVictim : IVictim
    {
        public string SharedProp { get; set; }

        public string PopProperty { get; set; }
    }

    public class MyGenericVictim
    {
        //Optional Property
        public bool? IsTroopVictim
        {
            get
            {
                if (Victim == null) return null;
                return Victim.GetType() == typeof(TroopVictim);
            }
        }

        public IVictim Victim { get; set; }
    }


    public class UseMyOfVictim
    {
        public void Bar()
        {
            Foo(new MyGenericVictim
            {
                Victim = new TroopVictim(),
            });
        }

        public void Foo(MyGenericVictim myvic)
        {
            //Function doesnt know TroopVic or PopVic

            TroopVictim resolvedTroopVic;
            PopVictim resolvedPopVictim;

            if (myvic.Victim.GetType() == typeof(TroopVictim))
            {
                resolvedTroopVic = (TroopVictim) myvic.Victim;
            }
            else if (myvic.Victim.GetType() == typeof(PopVictim))
            {
                resolvedPopVictim = (PopVictim) myvic.Victim;
            }

            string success = resolvedPopVictim.PopProperty;
            success = resolvedTroopVic.TroopProperty;
        }
    }

【讨论】:

  • 嗯,我的主要要求是保留相关部队/人口对象的连接/外键。在这里,我只会创建新的,这对我的问题没有帮助。我想我只需要让部队/人口从受害者那里继承……还是我在这里误解了什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多