【问题标题】:fixed values for property c#属性 c# 的固定值
【发布时间】:2017-08-04 15:51:09
【问题描述】:

我有一个Movement 类作为我的对象的属性。

我想要做的只是能够为此属性设置确定的值,例如:

class Movement
{
    public Direction Moving;
    public Direction Facing;
}

Movement movement = new Movement():

movement.Moving = Direction.Up;
movement.Facing = Direction.Down;

我可以将Direction.Up/Down/Left/Right 设为常量字符串,但我不想为属性设置任何不是Direction.Up/Down/Left/Right' 的东西。

但我不知道如何制作 Direction 类。

【问题讨论】:

  • 你需要的是一个枚举;不过做一些研究;这个问题看起来你没有花太多精力去寻找如何做你想做的事
  • 您希望智能感知仅向您显示可用选项还是真正限制任何其他值?
  • 为什么这个投票如此低,我见过更糟糕的问题。我很高兴人们真正考虑他们可能使用哪些类型,而不仅仅是使用一些字符串。那么,如果他不立即提出枚举怎么办,他可能是该语言的新手。

标签: c# object


【解决方案1】:

一种方法是使用Enum

public enum Direction 
{
    Up,
    Down,
    Left,
    Right
}

那么,如果您需要确保存储的 int 值是您的枚举的有效值:Is there a way to check if int is legal enum in C#?

【讨论】:

  • 好吧,严格来说,这不会修复价值,没有什么能阻止你写movement.Moving = (Direction)42;
  • @Davig,而您所说的在技术上是正确的。这对于这样的上下文无关紧要。
  • 我认为@DavidG 意味着您可以使用 Enum.IsDefined 或其他名称添加强制代码。
  • @MatthewWhited 你怎么可能知道 OP 在寻找什么,尤其是当你考虑到问题的倒数第二句话时?
  • 不,这是关于做最好的事情,而不是制造额外的废话,其他人以后必须删除或维护。
【解决方案2】:

您可以使用枚举并像这样使用它:

public enum Direction {
    1 = Up,
    2 = Right,
    3 = Down,
    4 = Left
}

public class UseDirection {
    public Direction Dir { public get; private set; }

    public void SetDirection(Direction dir) {
         Dir = dir;
    }
}

但是,现在如果你想对 Directions 做一些操作,或者做一些计算,你不能在 Direction 中实现它,因为它是一个枚举。

你也可以创建一个抽象类Direction,并让实际的方向派生自Direction,像这样:

public abstract class Direction {


    private class DirectionUp : Direction { }
    private class DirectionDown : Direction { }
    private class DirectionLeft : Direction { }
    private class DirectionRight : Direction { }

    public static Direction Up => new DirectionUp();
    public static Direction Down => new DirectionDown();
    public static Direction Left => new DirectionLeft();
    public static Direction Right => new DirectionRight();
}

现在你可以像这样使用Direction

public class AggregatesDirection {
     public Direction Dir { public get; private set; }

    public AggregatesDirection() {
         Dir = Direction.Up; //uses the static property in Direction that will use the private constructor of the private class in Direction.
    }
}

这种模式很好,因为您现在可以只使用Direction 接口来完成与方向相关的所有事情,并且仍然有不同的实现,例如,当您将某个给定方向的某些东西重新定位到不同的方向时类。

您也可以只将类公开并在抽象 Direction 类之外,但是您会将类型公开给命名空间,这可能没有必要。

【讨论】:

  • 你为什么不直接使用setter?
  • 呃,随便我随便打了几下,我可能想先把它设为私有,然后再决定什么,也懒得往回滚动,你认为我应该让它更整洁吗为了避免这种混乱? getter 和 setter 与我提议的模式无关
  • 错误:Direction.DirectionUp 比 Direction.Down 更难访问我之前尝试过这种方法
  • 如果是这种情况,你的基类有错误的可访问性。
  • "Direction.DirectionUp 比 Direction.Down 更难访问" 你是如何设法得到这个错误的?关于 up 和 down 我的意思是,还要确保静态属性和抽象类都具有 public 可访问性修饰符。
【解决方案3】:

我想通了,这就是我的诀窍:

public class Direction
    {
        private string value;

        private Direction(string value)
        {
            switch (value)
            {
                case "left":
                    {
                        this.value = value;
                        break;
                    }
                case "right":
                    {
                        this.value = value;
                        break;
                    }
                case "up":
                    {
                        this.value = value;
                        break;
                    }
                case "down":
                    {
                        this.value = value;
                        break;
                    }
                default:
                    throw new Exception("Valor invalido");
            }
        }

        public static class Directions
        {
            public static Direction Up = new Direction("up");
            public static Direction Down = new Direction("down");
            public static Direction Left = new Direction("left");
            public static Direction Right = new Direction("right");
        }
    }  

我将'Direction'类设为public,但它的构造函数设为私有,所以它只能在自身及其子类中实例化,然后在其中创建静态类'Directions'。

所以我可以轻松:

this.directionMoving = Direction.Directions.Down;
this.directionLooking = Direction.Directions.Down;

在我的代码中的任何地方,但不能:

Direction move = new Direction();

因为它的构造函数只能在其内部访问。

【讨论】:

  • 你现在打算如何比较方向?您现在所能做的就是比较字符串,这基本上就是您要解决的问题。这不是解决您的问题的方法。
  • 像这样:this.directionMoving = Direction.Directions.Down; 'Direction.value' 不相关,我只比较对象。下载或使用我的课程的人都无法为“方向”类实例化新元素,复制该类并尝试一下
  • 在 c# 中,您无法像假设的那样比较对象。平等比较是通过参考。因此,如果您比较 2 个向上的方向,相等将失败,因为它们不是同一个对象。如果您要使用类型系统,则不必首先比较方向。你现在实施的方式有很多潜在的问题。
猜你喜欢
  • 2019-10-29
  • 2016-09-03
  • 2020-12-19
  • 1970-01-01
  • 2013-04-17
  • 2012-10-27
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多