为更好的组织分组变量

时间:2017-03-25 03:52:18

标签: c#

我的问题已经在这里提出过了一些问题:How to build a group of constant variables in c#但我觉得好像不是在问同样的问题。我会试着解释一下,请听我说。

假设您必须代表玩家的属性,例如力量,敏捷,耐力等。但与此同时,您还想列出与同一组不直接相关的其他属性。除了主要属性之外,您还可以拥有概率属性,例如准确性,逃避和致命一击。以及后勤属性,例如:Movement,Initiative和Jump。当然,这些属性用于不同的目的,因此,应该单独分组(或者至少在我看来它们应该)。我可以使用多个类来实现它:

namespace Example
{
    public class PrimaryAttributes
    {

        public int Strength { get; set; }
        public int Agility { get; set; }
        public int Stamina { get; set; }
        public int Intellect { get; set; }
        public int Willpower { get; set; }
        public int Spirit { get; set; }

        public PrimaryAttributes()
        {
            // Do stuff here
        }

        // Do more stuff here


    }
}

(续)

namespace Example
{
    public class ProbabilisticAttributes
    {

        public int Accuracy { get; set; }
        public int Evasion { get; set; }
        public int CriticalStrike { get; set; }

        public ProbabilisticAttributes()
        {
            // Do stuff here
        }

        // Do more stuff here


    }
}

(续)

namespace Example
{
    public class LogisticalAttributes
    {

        public int Movement { get; set; }
        public int Initiative { get; set; }
        public int Jump { get; set; }

        public LogisticalAttributes()
        {
            // Do stuff here
        }

        // Do more stuff here


    }
}

然后将它们全部放在一个类中,如下所示:

namespace Example
{
    public class Statistics
    {

        public PrimaryAttributes PrimaryAttributes { get; set; }
        public ProbabilisticAttributes ProbabilisticAttributes { get; set; }
        public LogisticalAttributes LogisticalAttributes { get; set; }

        public LogisticalAttributes()
        {
            PrimaryAttributes = new PrimaryAttributes();
            ProbabilisticAttributes = new ProbabilisticAttributes();
            LogisticalAttributes = new LogisticalAttributes();
        }

        // Do more stuff here


    }
}

这将实现能够按照" stats.PrimaryAttributes.Strength"的方式调用某些内容的效果,这是干净且有条理的。但是,我宁愿不这样做。我想在同一个类中托管所有变量,而不必使用其他类。那捕获的是什么?我仍然希望能够在扩展范围之后组织它们,或者我想可以称为命名空间;如果你愿意,可以选择一种分隔线。我不认为C#语言中存在这样的东西......或任何语言。但我想知道我有多接近复制这种行为。这是我正在寻找的一个例子(不是真正的C#,只是一个例子)。

namespace Example
{
    public class Attributes
    {
        group PrimaryAttributes // Imaginary "group" keyword.
        {
            int Strength { get; set; }
            int Agility { get; set; }
            int Stamina { get; set; }
            int Intellect { get; set; }
            int Wisdom { get; set; }
            int Spirit { get; set; }
        }

        group ProbabilisticAttributes // Imaginary "group" keyword.
        {
            int Evasion { get; set; }
            int Accuracy { get; set; }
            int CriticalStrike { get; set; }
        }

        group LogisticalAttributes // Imaginary "group" keyword.
        {
            int Movement { get; set; }
            int Initiative { get; set; }
            int Jump { get; set; }
        }

        public Attributes()
        {
            // Don't have to declare or initialize anything.
        }

        public int ReturnSomethingAmazing()
        {
            return this.PrimaryAttributes.Strength * this.PrimaryAttributes.Agility; // Notice the group accessor usage.
        }

        // Do more stuff here


    }
}

我希望你现在能看到我在说什么。我希望能够"范围"变量,但不使用单独的类。我也冒昧地考虑如何在编译时解析它。从本质上讲,组范围只是内联,所以myClassInstance.PrimaryAttributes.Strength

,将最小化为myClassInstance.Strength。范围实际上并不存在,只有程序员才能更好地促进组织,而不会在运行时在内存中消耗更多的对象。

为了结束这个,我想总结两个问题。

  

这是否可能使用当前的C#?

  

您认为这是向微软推荐的一个好建议吗?   是否添加了C#编程语言?

2 个答案:

答案 0 :(得分:2)

有了这样的问题,唯一可能的答案就是表达意见。有时人们会有不同的想法,有时他们不会,所以请耐心等待。

OOP有时会变得困难和混乱,但这就是我认为关于它以及我会做什么的方式。另外,我知道你想要在没有"单独的课程的情况下做到这一点。而我的建议恰恰相反。但我相信使用单独的摘要来做这件事就是你找到The Force,Luke "。

首先,让我们创建一个枚举来简化分组(以及在将来访问属性时取消分组):

public enum AttributeCategory
{
    Primary,
    Probabilistic,
    Logistical
}

现在,属性的概念是接口的一个非常好的候选者。让我们创建它并创建一个相关的抽象来减少和简化代码(是的,过度使用接口,但谁在乎:D ):

public interface IAttribute
{
    string AttributeName { get; }
    AttributeCategory Category { get; }
    int Value { get; }
}

public abstract class AttributeBase : IAttribute
{
    protected virtual string AttributeName { get; }
    protected virtual AttributeCategory Category { get; }
    protected virtual int Value { get; }
}

// Note: one might want to implement a generic type for value, something like AttributeBase<T> {... T Value { get; } }

现在让我们来定义一些额外的摘要,你会明白为什么我喜欢这样做以后这么做:

public abstract class PrimaryAttribute : AttributeBase
{
    protected override sealed AttributeCategory Category { get; } = AttributeCategory.Primary;
}

public abstract class ProbabilisticAttribute : AttributeBase
{
    protected override sealed AttributeCategory Category { get; } = AttributeCategory.Probabilistic;
}

public abstract class LogisticalAttribute : AttributeBase
{
    protected override sealed AttributeCategory Category { get; } = AttributeCategory.Logistical;
}

好的,现在我们可以实现实际属性:

public sealed class Strength : PrimaryAttribute
{
    protected override string AttributeName => "Strength";
}

public sealed class Stamina : PrimaryAttribute
{
    protected override string AttributeName => "Stamina";
}

public sealed class Accuracy : ProbabilisticAttribute
{
    protected override string AttributeName => "Accuracy";
}

public sealed class Initiative : LogisticalAttribute
{
    protected override string AttributeName => "Initiative";
}

&#34; mess&#34;我上面已经描述过,我们现在可以创建一个描述这些属性集合的类:

public abstract class AttributeCollectionBase
{
    protected virtual List<IAttribute> Attributes { get; } = new List<IAttribute>();
    protected virtual IEnumerable<IAttribute> Get(AttributeCategory category)
    {
        return Attributes.Where(a => a.Category == category);
    }

    protected AttributeCollectionBase()
    {
        // Yup, we'll need this one place with the constructor that lists the "default" attributes... Might be for the best, though.
        Attributes.Add(new Strength());
        Attributes.Add(new Stamina());
        Attributes.Add(new Accuracy());
        Attributes.Add(new Initiative());
    }
}

最后,我们可以创建此属性集合的实现:

public sealed class AttributeCollection : AttributeCollectionBase
{
    //... We don't need anything here to start. Maybe add something specific.
}

public class SomeCharacter
{
    //...
    public AttributeCollection Attributes { get; }
}

var someCharacter = new SomeCharacter();

现在,为什么要经历这一切痛苦?那么,现在如果有什么需要实现的话,那就说概率属性(一些通用计算) - 需要一个修改,在抽象类(新的虚方法)中。所有属性都需要进行任何更改?要调整的一段代码 - AttributeBase。曾经需要分离一些默认属性(对于不同类别的字符而言) - 只需要另一个AttributeCollectionBase实现,例如KnightAttributeCollection。最后,你实现&#34;按类型获取属性&#34;像这样的实现:

someCharacter.Attributes.Get(AttributeCategory.Logistical);

尽管如此,这是我个人分享的方式,它可能看起来是次优的或不太可理解的,并不仅仅意味着&#34; 它总是取决于&#34;。

答案 1 :(得分:1)

这是我想出的一种方式,不确定它是否值得,但你可能喜欢它:

public class Attributes
{
    // PrimaryAttributes
    public class PrimaryAttr
    {
        public int Strength { get; set; }
        public int Agility { get; set; }
        public int Stamina { get; set; }
        public int Intellect { get; set; }
        public int Wisdom { get; set; }
        public int Spirit { get; set; }
    }

    private PrimaryAttr _primaryAttr;
    public PrimaryAttr PrimaryAttributes
    {
        get
        {
            if (this._primaryAttr == null)
                this._primaryAttr = new PrimaryAttr();

            return this._primaryAttr;
        }
    }


    // ProbabilisticAttributes
    public class ProbabilisticAttr
    {
        public int Evasion { get; set; }
        public int Accuracy { get; set; }
        public int CriticalStrike { get; set; }
    }

    private ProbabilisticAttr _probabilisticAttr;
    public ProbabilisticAttr ProbabilisticAttributes
    {
        get
        {
            if (this._probabilisticAttr == null)
                this._probabilisticAttr = new ProbabilisticAttr();

            return this._probabilisticAttr;
        }
    }


    // LogisticalAttributes
    public class LogisticalAttr
    {
        public int Movement { get; set; }
        public int Initiative { get; set; }
        public int Jump { get; set; }
    }

    private LogisticalAttr _logisticalAttr;
    public LogisticalAttr LogisticalAttributes
    {
        get
        {
            if (this._logisticalAttr == null)
                this._logisticalAttr = new LogisticalAttr();

            return this._logisticalAttr;
        }
    }


    // Rest of the implementation    
    public Attributes()
    {
        // Don't have to declare or initialize anything.
    }

    public int ReturnSomethingAmazing()
    {
        return this.PrimaryAttributes.Strength * this.PrimaryAttributes.Agility; // Notice the group accessor usage.
    }

    // Do more stuff here


}