我的问题已经在这里提出过了一些问题: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#编程语言?
答案 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
}