C# 将变量分组以实现更好的组织

C# 将变量分组以实现更好的组织,c#,C#,这里已经有人问过我的问题了:但我觉得好像不是在问同样的问题。我会尽力解释的,请听我说完 假设你必须代表一个球员的属性,比如力量、敏捷性、耐力等,但同时你也想列出与同一组没有直接关系的其他属性。除了主要属性外,您还可以具有概率属性,例如准确性、规避和致命一击。以及后勤属性,如:移动、主动性和跳跃。当然,这些属性有不同的用途,因此,应该单独分组(或者至少在我看来应该是这样)。我可以使用多个类来实现这一点: namespace Example { public class PrimaryAtt

这里已经有人问过我的问题了:但我觉得好像不是在问同样的问题。我会尽力解释的,请听我说完

假设你必须代表一个球员的属性,比如力量、敏捷性、耐力等,但同时你也想列出与同一组没有直接关系的其他属性。除了主要属性外,您还可以具有概率属性,例如准确性、规避和致命一击。以及后勤属性,如:移动、主动性和跳跃。当然,这些属性有不同的用途,因此,应该单独分组(或者至少在我看来应该是这样)。我可以使用多个类来实现这一点:

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 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


    }
}
someCharacter.Attributes.Get(AttributeCategory.Logistical);
这将达到能够按照“stats.PrimaryAttributes.Strength”的思路调用某些东西的效果,这是干净且有组织的。然而,我宁愿不这样做。我希望在同一个类中托管所有变量,而不必使用其他类。有什么问题吗?我仍然希望能够在一个扩展的范围内组织它们,或者我猜可以称之为名称空间;一种分隔器,如果你愿意的话。我认为在C语言中不存在这样的东西……或者任何与此相关的语言。但我想知道我离复制这种行为有多近。下面是我正在寻找的一个例子(不是真正的C#,只是一个例子)

我希望你能明白我现在在说什么。我希望能够“范围”变量,但不使用单独的类。我还冒昧地考虑了如何在编译时解析它。本质上,组作用域只是内联的,因此
myClassInstance.PrimaryAttributes.Strength

,将最小化为
myClassInstance.Strength
。作用域实际上并不存在,它只是为了程序员更好地促进组织,而不需要在运行时在内存中花费更多的对象

最后,我想总结两个问题

使用当前的C#是否有可能做到这一点

你认为这是一个向微软推荐的好建议吗 作为C#编程语言的补充


这是我刚想到的一种方法,不确定是否值得,但你可能会喜欢:

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


}

对于这类问题,唯一可能的答案是表达意见。有时候人们会有不同的想法,有时候他们不会,所以请容忍我

OOP有时会变得困难和困惑,但以下是我对它的想法和我应该做的。另外,我知道你想在没有“单独的类”的情况下完成它,我的建议正好相反。但我相信使用单独的摘要是“找到原力,卢克”

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

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

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

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";
}
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());
    }
}
使用上面描述的“mess”,我们现在可以创建一个类来描述这些属性的集合:

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";
}
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());
    }
}
现在,为什么要经历这些痛苦?好的,现在如果需要为概率属性(一些通用计算)实现任何东西,那么需要在抽象类(新的虚拟方法)中进行一次修改。所有属性都需要更改吗?要调整的一段代码-
属性库
。是否需要分离一些默认属性(例如,对于不同的字符类)-只需要另一个
AttributeCollectionBase
实现,例如,
KnightAttributeCollection
。最后,您实现了“按类型获取属性”的实现,如下所示:

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


    }
}
someCharacter.Attributes.Get(AttributeCategory.Logistical);

然而,这是我个人分享的方式,它可能看起来/是次优的或是不可理解的,它只意味着“它总是取决于”这一事实。

在课堂上使用区域不会成功吗?或者您可以使用分部类并为每个组使用不同的文件。用
方法来组织它们没有什么错。您可能更喜欢
struct
,对于它们作为属性包的用途来说,它更详细一些。我认为你想得太多了,因为每个类别的
类提供的正是你所需要的。@Andrew,但不能通过区域名称访问区域。@Krythic是的,我理解,我不关心少数属性的堆分配。如果它们成为你的应用程序性能的瓶颈,那么我就吃我的鞋子:)再说一次,我认为你把一些已经有既定模式的东西过度复杂了。@mariocatch我不应该提到内存,因为它回避了我的整体观点。我只是想澄清一个可能的用法。我关心的是组织。关于内存,我不能给出两个答案,我只想要组织。正如其他人提到的,可变结构是一个更好的选择。我投了赞成票,只是因为你给了我你的时间和考虑。我不确定这是个好主意。这很有趣,但我想知道,对于像具有某些属性的类这样简单的东西,这是否不是总体架构。最终每个属性只有一个类(加上所有支持的类)!还记得OP(Krythic)问“不必使用其他类”吗D另外,如果其中一个不是
int
类型,该怎么办?最后,由于接口成员在类中不是公共的,那么代码不会给您带来错误吗?至少在我的本地计算机上没有编译。@Andrew,