.net c#使用静态方法创建默认对象?

Using Static Method to Create Default Object?
2021-07-22
  •  译文(汉语)
  •  原文(英语)

我正在构建一个用于我正在使用的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是另一种结构,它需要"数量的模具"来滚动,而短路则需要修改它.

对于上面的示例,我创建了一个新的4d6-d6卷.

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

感谢您的建议!

安德鲁

速聊1:
简短的旁注:您;;的第二个代码块上有一个.另外,建议您使用一个静态的Random对象,而不是每次都创建一个新的对象.(如果同时创建两个随机对象,则它们将创建完全相同的数字)
速聊2:
什么是(short)(-Die.d6().Roll())做什么?它很丑.
速聊3:
感谢您使用双分号,我会确定要清理的.因此,您建议我从单个模具中取出随机对象,然后将其作为参数传递?那将限制所创建对象的数量.
速聊4:
.模具对象具有称为Roll的方法,该方法将生成一个介于1和给定模具尺寸之间的随机数.在这种情况下,它将生成一个介于1到6之间的随机数,将其转换为-,然后通过类型转换将其转换为short以供Roll对象使用.最好不要让对象和方法具有相同的名称.:D
速聊5:
1)为什么限制为空头?2)3d的论点是做什么的?
解决过程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<T>:http : //msdn.microsoft.com/zh-cn/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; } }

    ...
}
速聊1:
帕特里克(Patrick),也许我听不懂,但我不介意在对象声明中将我的静态对象作为公共项打开,因为它们永远不会改变,并且它们仅作为单个实例被引用.一个特殊的双面模具.我认为不需要在这种简单的东西上进行额外的封装.如果它们是静态的,则永远不应更改.
速聊2:
尽管在第一次需要引用类型静态变量时就初始化它们并不重要,但它已成为我的标准模式.它可以防止未使用的静态变量消耗内存或浪费初始化它们所需的时间.在小型应用程序或小型类中,这无关紧要,但在具有非平凡的初始化步骤的较大对象上,创建从未使用过的对象会产生实际成本.
速聊3:
我已经更新了答案,以包括在字段上使用属性的基本原理,并添加了一个使用Lazy类清理代码的示例.
速聊4:
感谢Patrick为您介绍Lazy.这肯定比您的最初示例干净得多.

I'm working on building a die rolling program for use in an XNA project I'm using, but my question here is purely c# and is more on best practices or any gotchas I might need to look out for. Is it an effective use of a static method in an object's definition to outline the creation of default items.

Below is the snapshot of the code I'm using,

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);
    }
}

Using this my code seems to compile without issues when I make references to the Die struct:

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

Roll is another struct that takes a Quantity of Die to roll and a short to modify it by.

In the case of my sample above, I create a new roll of 4d6-d6.

Is this going to cause me any problems later down the line if I am creating new instances of these dice?

Thanks for the advice!

Andrew

Talk1:
Few quick sidenotes: You have a ;; on your second code block. Also, it's recommended that you use a single static Random object, instead of creating a new one every time. (If two Random objects are created at the same time, they will create the exact same numbers)
Talk2:
What is (short)(-Die.d6().Roll()) doing? It's ugly.
Talk3:
Thanks for the double semicolon, I'll get that cleaned up for sure. So you are suggesting that I take the random object out of the individual die and pass it instead as a parameter? That would put a limit on the number of objects that get created.
Talk4:
. The Die object has a method called Roll that will generate a random number between 1 and its given die size. In this case it will generate a random number between 1 and 6, invert it with the -, and then convert it to a short through typecasting for use in the Roll object. Probably not best to have an object and a method with the same name. :D
Talk5:
1) Why limit to short? 2) What does the 3d argument to roll do?
Solutions1

I add a static factory method to a lot of classes if I want to use them as a method group:

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

In this case, I would just replace the set of different factory methods with a set of static properties and lazy singletons:

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

}

I use these rather than just public static fields because I want to delay their creation until their first use.

That can be simplified with Lazy<T> : 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; } }

    ...
}
Talk1:
Patrick, maybe I'm not understanding, but I don't mind opening up my statics as public items in the object declaration because they won't ever be changing, and they are meant to be referenced as just that, a single instance of a particular sided die. I don't see the need for the extra encapsulation on something this simple. If they are static, they should never be changing.
Talk2:
While it isn't critical to only initialize your reference type statics the first time you need them, it has become my standard pattern. It prevents unused statics from consuming memory or wasting the time required to initialize them. It's not going to matter much in a small app or on tiny classes, but on larger objects that take have non-trivial initialization steps, there's a real cost to creating an object that's never used.
Talk3:
I've updated my answer to include my rationale for using properties over fields, and I added an example of using the Lazy class to clean up the code a bit.
Talk4:
Thanks Patrick for the introduction of Lazy. That definitely looks a lot cleaner than your initial example.
转载于:https://stackoverflow.com/questions/17377492/using-static-method-to-create-default-object

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入