我必须在C#中创建一个类,称之为Class1。该类必须包含一个名为Flag的枚举字段。标志有4个可能的值,比如A,B,C,D。 Class1的一个实例可以包含另一个Class1实例,其中Flag的状态与A不同。
我的问题是:如何制定子实例中Flag的状态必须与A不同的条件?
答案 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.