8

让我们建议我有一个接口并从中继承类,

internal interface IPersonInfo
{
    String FirstName { get; set; }
    String LastName { get; set; }
}
internal interface IRecruitmentInfo
{
    DateTime RecruitmentDate { get; set; }
}

public abstract class Collaborator : IPersonInfo, IRecruitmentInfo
{
    public DateTime RecruitmentDate
    {
        get;
        set;
    }
    public String FirstName
    {
        get;
        set;
    }
    public String LastName
    {
        get;
        set;
    }
    public abstract Decimal Salary
    {
        get;
    }
}

那么如何验证协作者类中的字符串?是否可以实现内部属性?

4

9 回答 9

9

是的,但不使用自动属性。您将需要使用支持字段手动实现属性:

private string firstName;

public String FirstName
{
    get
    {
        return firstName;
    }
    set
    {
        // validate the input
        if (string.IsNullOrEmpty(value))
        {
            // throw exception, or do whatever
        }
        firstName = value;
    }
}
于 2011-02-09T14:35:58.783 回答
6

像这样的东西...

private string _firstName;
public string FirstName
{
    get
    {
        return _firstName;
    }
    set
    {
        if (value != "Bob")
          throw new ArgumentException("Only Bobs are allowed here!");
        _firstName = value;
    }
}

基本上,您用于属性的是语法糖版本。在编译时,他们创建一个私有成员变量并连接属性以使用该变量,就像我在这里手动做的那样。这样做的确切原因是,如果您想添加逻辑,您可以像我在这里一样将其转换为手动逻辑,而不会破坏接口的实现。

于 2011-02-09T14:37:34.040 回答
3

或者使用 DataAnnotations

http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute.aspx

于 2011-02-09T14:39:17.120 回答
3

如果您变得更加复杂,还应该提及验证框架。它们可以使验证规则更易于管理,并且还会向您的 UI 显示错误,同时保持规则与您的模型相关联,这样您就不必拥有任何重复的样板验证代码。根据您的框架版本,一种选择是DataAnnotations

于 2011-02-09T14:41:27.580 回答
2

据我所知,如果您使用自动属性语法,您将失去访问支持字段的能力。根据文档(http://msdn.microsoft.com/en-us/library/bb384054.aspx):

在 C# 3.0 及更高版本中,当属性访问器中不需要额外的逻辑时,自动实现的属性使属性声明更加简洁。它们还使客户端代码能够创建对象。如下例所示声明属性时,编译器会创建一个私有的匿名支持字段,该字段只能通过属性的 get 和 set 访问器访问。

在自动实现的属性上允许使用属性,但显然不允许在支持字段上使用属性,因为这些属性无法从您的源代码中访问。如果您必须在属性的支持字段上使用属性,只需创建一个常规属性。

因此,您唯一的解决方案是创建常规属性。

于 2011-02-09T14:37:18.740 回答
0

是的。您可以为该属性创建一个私有支持字段,如下所示:

private String _firstName;

public String FirstName
{
     get
     {
          return _firstName;
     }
     set
     {
          //Check value for correctness here:
          _firstName = value;
     }
}
于 2011-02-09T14:36:21.630 回答
0
private DateTime recruitmentDate;    
public DateTime RecruitmentDate
{
    get { return recruitmentDate; }
    set
    {
        validate(value);
        recruitmentDate = value;
    }
}
于 2011-02-09T14:36:44.120 回答
0

如果您的意思是您可以在 C# 中获取/设置属性期间执行自定义逻辑,那么答案是肯定的。

您使用所谓的自动属性,其中默认为您提供后备存储和逻辑。

您只需要自己提供即可

private int backingStoreVariable;
public property MyProperty
{
    get
    {
        return this.backingStoreVariable;
    }
    set
    {
        this.backingStoreVariable=value;
    }
}

现在,您可以在 get 和 set 块中运行自定义验证代码。

于 2011-02-09T14:37:20.857 回答
0

或者,您不能为您的字段使用值类型。例如,您可以使用以下实现创建一个“FirstName”类:

public class FirstName
{
    private string _Value;
    public string Value
    {
        get
        {
            return _Value;
        }
        set
        {
            if (string.IsNullOrEmpty(value))
                throw new ArgumentNullException("Value cannot be null");
            if (value.Length > 128)
                throw new ArgumentOutOfRangeException("Value cannot be longer than 128 characters");
            _Value  = value;
        }
    }

    public FirstName(string initialValue)
    {
        Value   = initialValue; //does validation check even in constructor
    }
}

最后,在上面的代码示例中,您只需:

public interface IPersonInfo
{
    FirstName FirstName { get; set; }
    String LastName { get; set; }
}

等等与您的其他属性。然后要在您的代码中使用该属性,您将拥有:

public FirstName MyFirstName;
var x = MyFirstName.Value;

如果您有很多要验证的字段,这可能最终会成为一种繁琐的方法。但是,您可以将其概括为处理某些类型的数字 - 例如正数 ( ints > 0) 或计数 ( int >= 0)、度量等。

字符串更难,因为除了值类型(例如没有特殊字符、没有数字等)之外,它们通常还有长度限制。这可以通过在继承类的构造函数中设置的只读长度属性来适应.

于 2013-05-20T20:08:10.067 回答