我想使用静态类为我的应用程序创建配置。
首先请原谅我的无知,我不是全职的c#dev。我来自Ruby / Javascript世界,其中动态访问常量和&变量很简单。
这是否是正确的方法我现在不是百分之百。会很高兴其他建议的方法。
我的配置有以下静态类设置:
public static class Config
{
public static class MaterialQuality
{
public static class Low
{
public const float Value = 0.1f;
public const int Cost = 10;
}
public static class Medium
{
public const float Value = 0.2f;
public const int Cost = 20;
}
public static class High
{
public const float Value = 0.2f;
public const int Cost = 40;
}
}
}
然后我有一个类Material
,它传递一个与上述类型Low,Medium,High
相关的枚举值。
enum
统一的原因为开发人员提供了一种快速方法,可以为关卡设计人员提供一个对象的选项列表。
因此,通过选择枚举值,关卡设计人员可以设置存储在配置中的属性,而无需直接在对象上输入值。初始化时,将针对对象设置值。
在构造函数中,我想为Cost
&设置成员变量。来自Value
枚举值的静态配置值的MaterialQuality
。
public enum MaterialQuality
{
Low,Medium,High
}
public class Material
{
private int Cost;
private float Value;
Material(MaterialQuality quality) {
Cost = Config.MaterialQuality.<quality>.Cost;
Value = Config.MaterialQuality.<quality>.Value;
//in Javascript I'd use associative array access to the object
Cost = Config.MaterialQuality[quality].Cost;
//in Ruby we have const_get() on classes.
Cost = Config.MaterialQuality.const_get(quality).Cost
}
}
这种方法的主要原因是为配置和提供单一的位置。为非技术人员提供一种相当简单的方法来更改应用程序的各个部分,而无需深入研究主要类。它还允许我利用intellisense中可用的常量。
答案 0 :(得分:2)
我喜欢使用字典进行此类配置。
void Main()
{
var config = Config.Qualities[MaterialQualities.Low];
var cost = config.Cost;
var value = config.Value;
}
public static class Config
{
public static Dictionary<MaterialQualities, MaterialQuality> Qualities =
new Dictionary<MaterialQualities, MaterialQuality>
{
{ MaterialQualities.Low, new MaterialQuality { Value = 0.1F, Cost = 10 }},
{ MaterialQualities.Medium, new MaterialQuality { Value = 0.2F, Cost = 20 }},
{ MaterialQualities.High, new MaterialQuality { Value = 0.2F, Cost = 40 }},
};
}
public class MaterialQuality
{
public float Value { get; set; }
public int Cost { get; set; }
}
public enum MaterialQualities
{
Low, Medium, High
}
答案 1 :(得分:1)
可能更好的方法是:
public static class Config
{
public class Material
{
public Material(float value, int cost){
Value = value;
Cost = cost;
}
public float Value {get; private set;}
public int Cost {get; private set;}
public Material GetFor(MaterialQuality quality){
switch(quality){
case MaterialQuality.Low: return new Material(0.1f, 10);
case MaterialQuality.Medium: return new Material(0.2f, 20);
case MaterialQuality.High: return new Material(0.2f, 40);
}
throw new Exception("Unknown material quality " + quality);
}
}
}
以后你可以使用它:
//....
Material materialData = Material.GetFor(quality);
Cost = materialData.Cost;
Value = materialData.Value;
//...
答案 2 :(得分:1)
我会在MaterialQuantity中使用struct和static属性而不是enum。如下所示:
public struct MaterialQualityInfo
{
public MaterialQualityInfo( float value, int cost )
{
Value = value;
Cost = cost;
}
public float Value { get; private set; }
public int Cost { get; private set; }
}
public static class Config
{
public static class MaterialQuality
{
public static MaterialQualityInfo Low
{
get { return new MaterialQualityInfo( 0.1f, 10 ); }
}
public static MaterialQualityInfo Medium
{
get { return new MaterialQualityInfo( 0.2f, 20 ); }
}
public static MaterialQualityInfo High
{
get { return new MaterialQualityInfo( 0.2f, 40 ); }
}
}
}
public class Material
{
private int Cost;
private float Value;
Material( MaterialQualityInfo quality )
{
Cost = quality.Cost;
Value = quality.Value;
}
}
答案 3 :(得分:1)
我发现所有材质都有2个共同属性:Value
和Cost
。对我来说,这意味着你应该设计一个名为MaterialQuality
的类:
public class MaterialQuality
{
public float Value { get; set; }
public int Cost { get; set; }
}
如果材质是应用程序配置的一部分,我发现您应该按如下方式设计Configuration
类:
public class Configuration
{
public List<MaterialQuality> MaterialQualities { get; } = new List<MaterialQuality>();
}
...如果您想按应用程序生命周期初始化配置,可以使用静态字段初始化程序改进Configuration
类:
public class Configuration
{
private readonly static Configuration _current = new Configuration();
public static Configuration Current => _current;
public List<MaterialQuality> MaterialQualities { get; } = new List<MaterialQuality>();
}
现在,将新材料质量添加到当前配置就像下面的代码一样简单:
Configuration.Current.MaterialQualities.Add(new MaterialQualities { Value = 0.1f, Cost = 10 });
如果您想提供一个流畅的API来添加材料质量也很容易:我们将公共MaterialQualities
属性转换为ImmutableList<T>
(,因此您强制开发人员使用方法添加材料)并添加AddMaterial
方法:
public class Configuration
{
private readonly static Configuration _current = new Configuration();
private readonly List<MaterialQuality> _materialQualities = new List<MaterialQuality>();
public static Configuration Current => _current;
public IImmutableList<MaterialQuality> MaterialQualities => _materialQualities.ToImmutableList();
public Configuration AddMaterial(float value, int cost)
{
_materialQualities.Add(new MaterialQuality { Value = value, Cost = cost });
return this;
}
}
...现在添加许多材料会更好看!
Configuration.Current.AddMaterial(0.1f, 10)
.AddMaterial(0.2f, 20)
.AddMaterial(0.2f, 40);
答案 4 :(得分:0)
怎么样:
public enum MaterialQuality
{
Low, Medium, High
}
public class Material
{
private int Cost;
private float Value;
private readonly Dictionary<MaterialQuality, Tuple<int, float>> storageMap = new Dictionary<MaterialQuality, Tuple<int, float>>
{
{ MaterialQuality.Low, Tuple.Create(10, 0.1f)},
{ MaterialQuality.Low, Tuple.Create(20, 0.2f)},
{ MaterialQuality.Low, Tuple.Create(40, 0.2f)},
};
public Material(MaterialQuality quality)
{
Cost = storageMap[quality].Item1;
Value = storageMap[quality].Item2;
}
}
答案 5 :(得分:0)
如果你没有广泛使用你的枚举,你可以做类似的事情:
public class Material
{
public float Value { get; private set; }
public int Cost { get; private set; }
public Material(float value, int cost)
{
Value = value;
Cost = cost;
}
public static Material Low { get { return new Material(0.1f, 10); } }
public static Material Medium { get { return new Material(0.2f, 20); } }
public static Material High { get { return new Material(0.2f, 40); } }
}
然后:
var myLowMaterial = Material.Low;
var myMediumMaterial = Material.Medium;
var myHighMaterial = Material.High;
除非您使用enum
作为某些内容,否则您可以添加:
public static Material Get(MaterialQuality quality)
{
switch(quality)
{
case MaterialQuality.Low:
return Low;
case MaterialQuality.Medium:
return Medium;
case MaterialQuality.High:
return High;
}
throw new Exception("We should never go here");
}