【问题标题】:Using Static Method to Create Default Object?使用静态方法创建默认对象?
【发布时间】:2013-06-30 00:20:39
【问题描述】:

我正在构建一个用于我正在使用的 XNA 项目的掷骰子程序,但我的问题纯粹是 C#,更多的是关于最佳实践或我可能需要注意的任何问题。在对象定义中使用静态方法来勾勒默认项的创建是否有效?

下面是我正在使用的代码的快照,

public struct Die{
    private DieType die;
    private static Random rnd = new Random();
    public static Die d2 = new Die(DieType.d2);
    public static Die d4 = new Die(DieType.d4);
    public static Die d6 = new Die(DieType.d6);
    public static Die d8 = new Die(DieType.d8);
    public static Die d10 = new Die(DieType.d10);
    public static Die d12 = new Die(DieType.d12);
    public static Die d20 = new Die(DieType.d20);
    public static Die d100 = new Die(DieType.d100);

    public Die(DieType die){
        this.die = die;
    }

    public int Roll(){
        return rnd.Next((int)die);
    }
}

当我引用 Die 结构时,我的代码似乎可以毫无问题地编译:

List <Roll> diceCup = new List<Roll>();
diceCup.Add (new Roll(4,Die.d6,-Die.d6.Roll()));

Roll 是另一个结构体,它需要一个 Quantity of Die 来滚动和一个 short 来修改它。

在上面的示例中,我创建了一个新的 4d6-d6 卷。

如果我要创建这些骰子的新实例,这是否会在以后给我带来任何问题?

感谢您的建议!

安德鲁

【问题讨论】:

  • 几个快速的旁注:你的第二个代码块上有一个;;。此外,建议您使用单个静态 Random 对象,而不是每次都创建一个新对象。 (如果同时创建两个 Random 对象,它们将创建完全相同的数字)
  • (short)(-Die.d6().Roll()) 在做什么?太丑了。
  • @mcmonkey4eva 谢谢你的双分号,我一定会把它清理干净。所以你建议我从单个骰子中取出随机对象并将其作为参数传递?这将限制创建的对象数量。
  • @保罗。 Die 对象有一个名为 Roll 的方法,它将生成一个介于 1 和其给定 die 大小之间的随机数。在这种情况下,它将生成一个介于 1 和 6 之间的随机数,用 - 反转它,然后通过类型转换将其转换为 short 以用于 Roll 对象。拥有同名的对象和方法可能不是最好的。 :D
  • 1) 为什么限制做空? 2) roll 的 3d 参数有什么作用?

标签: c# xna xna-4.0


【解决方案1】:

如果我想将它们用作方法组,我会在很多类中添加一个静态工厂方法:

var people = names.Select(Person.Create);

在这种情况下,我只需将一组不同的工厂方法替换为一组静态属性和惰性单例:

public class Die
{
    private static Die _d2;

    public static Die D2
    {
        get
        {
            if(_d2 == null)
                _d2 = new Die(DyeType.D2);

            return _d2;
        }
    }

    private static Die _d3 ...

}

我使用这些而不仅仅是公共静态字段,因为我想将它们的创建延迟到它们第一次使用。

这可以用Lazy&lt;T&gt; 来简化:http://msdn.microsoft.com/en-us/library/dd642331.aspx

public class Die
{
    private static readonly Lazy<Die> _d2 = new Lazy<Die>(() => new Die(DyeType.D2));
    private static readonly Lazy<Die> _d3 = new Lazy<Die>(() => new Die(DyeType.D3));
    private static readonly Lazy<Die> _d4 = new Lazy<Die>(() => new Die(DyeType.D4));

    public static Die D2 { get { return _d2.Value; } }
    public static Die D3 { get { return _d3.Value; } }
    public static Die D4 { get { return _d4.Value; } }

    ...
}

【讨论】:

  • Patrick,也许我不明白,但我不介意在对象声明中将我的静态数据作为公共项目打开,因为它们永远不会改变,它们应该被引用就这样,一个特定的单面模具的单个实例。我认为不需要对这么简单的东西进行额外的封装。如果它们是静态的,则它们永远不应该改变。
  • 虽然只在第一次需要引用类型静态变量时才初始化它们并不重要,但它已成为我的标准模式。它可以防止未使用的静态变量消耗内存或浪费初始化它们所需的时间。在小型应用程序或小型类中,这并不重要,但在具有非平凡初始化步骤的较大对象上,创建从未使用过的对象会产生实际成本。
  • 我已经更新了我的答案以包含我在字段上使用属性的基本原理,并且我添加了一个使用 Lazy 类来稍微清理代码的示例。
  • 感谢 Patrick 介绍 Lazy。这绝对看起来比你最初的例子干净得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多