包含同一个类

时间:2015-06-10 09:04:18

标签: c# .net class enums

我必须在C#中创建一个类,称之为Class1。该类必须包含一个名为Flag的枚举字段。标志有4个可能的值,比如A,B,C,D。 Class1的一个实例可以包含另一个Class1实例,其中Flag的状态与A不同。

我的问题是:如何制定子实例中Flag的状态必须与A不同的条件?

3 个答案:

答案 0 :(得分:2)

标记你的Class1" subinstance"作为私人,只能通过财产访问。在属性设置器中,检查所设置的值是否具有与父设备不同的标志。请注意,如果父Class1标志必须始终与子项不同,那么您还必须在设置父标志时添加一个检查。

答案 1 :(得分:2)

您可以将setter设为私有并在构造函数中检查它,您还必须为内部实例提供私有构造函数。所以基本上是一个不可变的类:

public enum Flag
{
    A, B, C, D
}

public class Class1
{
    private Class1 _Class1Inner;
    public Class1 Class1Inner
    {
        get { return _Class1Inner; }
        private set { _Class1Inner = value; }
    }

    private Flag _Flag;
    public Flag Flag
    {
        get { return _Flag; }
        private set { _Flag = value; }
    }

    // used only to create the inner instance
    private Class1(Flag innerFlag)
    {
        this.Flag = innerFlag;
        _Class1Inner = null; // or whatever 
    }

    public Class1(Flag flag, Flag innerFlag)
    {
        if (innerFlag == Flag.A)
            throw new ArgumentException("innerFlag must not be Flag.A!", "innerFlag");
        this.Flag = flag;
        this.Class1Inner= new Class1(innerFlag);
    }
}

如果您希望此类是可变的,那么您可以在创建后更改Flag,您必须记住它是否是内部实例。

因此,您需要另一个可以从构造函数设置的字段:

public class Class1
{
    private bool _isInnerInstance = false;

    private Class1 _Class1Inner;
    public Class1 Class1Inner
    {
        get { return _Class1Inner; }
        private set { _Class1Inner= value; }
    }

    private Flag _Flag;
    public Flag Flag
    {
        get { return _Flag; }
        set
        {
            if (_isInnerInstance && value == Flag.A)
                throw new ArgumentException("innerFlag must not be Flag.A!", "innerFlag");
            _Flag = value;
        }
    }

    private Class1(Flag innerFlag)
    {
        this.Flag = innerFlag;
        _isInnerInstance = true;
        _Class1Inner = null; // or whatever
    }

    public Class1(Flag flag, Flag innerFlag)
    {
        if (innerFlag == Flag.A)
            throw new ArgumentException("innerFlag must not be Flag.A!", "innerFlag");
        this.Flag = flag;
        _Class1Inner = new Class1(innerFlag);
    }
}

现在不允许关注:

Class1 cls1 = new Class1(Flag.A, Flag.B);
cls1.Class1Inner.Flag = Flag.A; // throws an ArgumentException at runtime

答案 2 :(得分:0)

作为评论开始,但有点过于详细,所以动了回答......

首先,我会说Class1需要一种知道它是'子实例'的方法,例如你可以强制一个定义它的构造函数:

private IsSub { get; set; }
public Class1(bool isSub)
{
    IsSub = isSub;
}

在类中设置属性。此属性可用于检查Flag是否可以A。但是你需要一种方法来验证标志何时被设置。为此,您可以添加一个向属性设置器抛出错误的验证方法:

private Flag myFlag;
public Flag MyFlag 
{
    get { return myFlag; }
    set { ValidateFlag(value); myFlag = value; }
} 

void ValidateFlag(Flag flag)
{
    if(IsSub && flag == Flag.A)
        throw new Exception("Invalid flag");
}

最后,您需要决定何时设置子实例。如果你只想允许一个级别的子实例(所以子类没有自己的子实例),那么你可以在默认构造函数中这样做:

public Class1 ChildClass { get; set; }
public Class1()
{
    ChildClass = new Class1(true);
}

(您还需要考虑如何设置标志属性的默认值,但这是您决定的逻辑。)

以下是示例用法:

Class1 myClass = new Class1();
myClass.MyFlag = Flag.A; // This is fine.
myClass.SubClass.MyFlag = Flag.A; // This will throw an exception.