如何在C#中的getter和setter方法中进行验证?

如何在C#中的getter和setter方法中进行验证?,c#,.net,vb6,syntax,automatic-properties,C#,.net,Vb6,Syntax,Automatic Properties,在C#中,我可以拥有一个属性,而无需声明私有变量。 我的VB6代码看起来像这样 'local variable(s) to hold property value(s) Private mvarPhoneNumber As String 'local copy Public Property Let PhoneNumber(ByVal vData As String) 'used when assigning a value to the property, on the left side o

在C#中,我可以拥有一个属性,而无需声明私有变量。 我的VB6代码看起来像这样

'local variable(s) to hold property value(s)
Private mvarPhoneNumber As String 'local copy
Public Property Let PhoneNumber(ByVal vData As String)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.PhoneNumber = 5
    mvarPhoneNumber = vData
End Property


Public Property Get PhoneNumber() As String
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.PhoneNumber
    PhoneNumber = mvarPhoneNumber
End Property
现在可以像这样了

public string PhoneNumber{get;set;}
public string PhoneNumber
        {
            get
            {
                return PhoneNumber;
            }
            set
            {
                if (value.Length <= 30)
                {
                    PhoneNumber = value;
                }
                else
                {
                    PhoneNumber = "EXCEEDS LENGTH";
                }
            }
        }
如何在C#中的getter和setter方法中进行验证? 我尝试添加这样的验证

public string PhoneNumber{get;set;}
public string PhoneNumber
        {
            get
            {
                return PhoneNumber;
            }
            set
            {
                if (value.Length <= 30)
                {
                    PhoneNumber = value;
                }
                else
                {
                    PhoneNumber = "EXCEEDS LENGTH";
                }
            }
        }
公共字符串电话号码
{
得到
{
返回电话号码;
}
设置
{

如果(value.Length是,则必须创建一个支持字段:

string _phoneNumber;

public string PhoneNumber
{
    get
    {
        return _phoneNumber;
    }
    set
    {
        if (value.Length <= 30)
        {
            _phoneNumber = value;
        }
        else 
        {
            _phoneNumber = "EXCEEDS LENGTH";
        }
    }
}
string\u phoneNumber;
公共字符串电话号码
{
得到
{
返回电话号码;
}
设置
{

如果(value.Length是,您可以。当您使用快捷方式“隐式”语法时,它会秘密为您创建一个名为_phoneNumber的支持字段。当您显式定义属性时,您需要创建自己的支持字段。在属性定义的正上方放置:

private string _phoneNumber;
然后在您的财产中使用:

get
{
    return _phoneNumber;
}

在这里可以找到多种备选方案:


但简短的回答是肯定的,您必须有用于验证的支持字段。

您不一定需要局部变量。理论上,您可以在
get
/
set
属性中实现您想要的任何功能。但是,在您的示例中,您可以递归访问
get
/
属性。因此,在您的具体案例中,您将需要一个局部变量,这是正确的。

我会这样做,以避免出现
NullReferenceException
,并缩短整个代码

public string PhoneNumber
{
    get { return _phoneNumber; }
    set 
    {
        var v = value ?? string.Empty; 
        _phoneNumber = v.Length <= 30 ? v : "EXCEEDS LENGTH"; 
    }
}
private string _phoneNumber;
公共字符串电话号码
{
获取{return\u phoneNumber;}
设置
{
var v=值??字符串。为空;

_phoneNumber=v.Length正如Andrew所说,您需要为属性创建一个私有变量。C#的自动属性功能实际上在幕后为您实现了这一点,但您不能以这种方式访问该私有变量。您必须显式声明它以对其执行任何操作(例如验证它)另外,请确保在setter中设置backing字段,否则在运行时会遇到StackOverflowException。我不知道您是否只是为了举例而简化,但盲目地将属性设置为新值而不是抛出ArgumentException似乎很令人担忧。我将稍微偏离主题,回应您的介绍VB6等价于C#auto属性
公共字符串PhoneNumber{get;set;}
实际上是一个简单的公共字段,
公共电话号码为字符串
。在VB6中,您可以随意将公共字段交换为属性,而不影响任何功能:呼叫者不需要重新编译,数据绑定仍然有效…这是VB6优于.Net的一个领域。谢谢。我不确定是否需要。我认为这不是呼叫类似于这样,但是有一个很长很难看的名称,最好在getter中处理null值,而不是setter。如果在初始化属性之前访问getter会怎么样?我会将get改为{return\u phoneNumber??string.Empty;}。此外,如果指定的值太长,您应该抛出异常,而不是用任意值替换它。@Chris,如果PhoneNumber不能为null(这里的答案假设为null),则必须在setter和构造函数中捕获它(构造函数不应使其对象处于无效状态)。或者,如果它可以为null,那么它应该只返回null而不进行任何检查(并且该检查已更改为允许该检查)@Chris-我个人认为他们的验证能力很弱,但这有点离题。我就是无法忍受代码容易受到
NullReferenceException
的攻击,因为它很容易解决。@Jon的评估绝对正确,尽管我可能会更进一步,使用一个不可变的对象。如果你要要绝对确保将私有变量初始化为非null值,并且绝对不能在私有变量中存储null值,请确保在setter中阻止它。这是我的一般经验,但我们讨论的是确保任何引用该属性的外部类都不会获得null referencece异常,在这种情况下,在getter中处理它更干净,更不冗长。