簡體   English   中英

驗證c#中的屬性

[英]Validating properties in c#

我建議我有一個接口並從中繼承類,

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;
    }
}

那么如何驗證協作者類中的字符串? 是否可以實現內部屬性?

是的,但不使用自動屬性。 您需要使用支持字段手動實現屬性:

private string firstName;

public String FirstName
{
    get
    {
        return firstName;
    }
    set
    {
        // validate the input
        if (string.IsNullOrEmpty(value))
        {
            // throw exception, or do whatever
        }
        firstName = value;
    }
}

像這樣......

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

基本上,你用於屬性的是語法糖版本。 在編譯時,他們創建一個私有成員變量並連接屬性以使用該變量,因為我在這里手動完成。 這樣做的確切原因是,如果你想添加邏輯,你可以將它轉換成手動的,就像我在這里一樣,而不會破壞界面的實現。

如果你有點復雜,還應該提一下驗證框架。 它們可以使驗證規則更易於管理,並且還會向UI顯示錯誤,同時保持規則與模型相關聯,因此您不必具有任何重復的樣板驗證代碼。 根據您的框架版本,一個選項是DataAnnotations

據我所知,如果使用自動屬性語法,則無法訪問支持字段。 根據文檔(http://msdn.microsoft.com/en-us/library/bb384054.aspx):

在C#3.0及更高版本中,當屬性訪問器中不需要其他邏輯時,自動實現的屬性使屬性聲明更簡潔。 它們還使客戶端代碼能夠創建對象。 當您聲明屬性時,如以下示例所示,編譯器將創建一個私有的匿名支持字段,該字段只能通過屬性的get和set訪問器進行訪問。

允許在自動實現的屬性上使用屬性,但顯然不在支持字段上,因為無法從源代碼訪問這些屬性。 如果必須在屬性的支持字段上使用屬性,只需創建常規屬性。

因此,您唯一的解決方案是創建常規屬性。

或者,您不能為字段使用值類型。 例如,您可以使用以下實現創建“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; }
}

等等你的其他財產。 然后要在您的codel中使用該屬性,您將擁有:

public FirstName MyFirstName;
var x = MyFirstName.Value;

如果您有許多要驗證的字段,這可能最終會成為一種繁瑣的方法。 但是,您可以將其概括為處理某些類型的數字 - 例如正數( ints > 0 )或count( int >= 0 ),度量等。

字符串更難,因為它們除了值類型之外通常還有長度限制(例如沒有特殊字符,沒有數字等。這可能通過在繼承類的構造函數中設置的只讀長度屬性來適應。

是。 您可以為屬性創建私有支持字段,如下所示:

private String _firstName;

public String FirstName
{
     get
     {
          return _firstName;
     }
     set
     {
          //Check value for correctness here:
          _firstName = value;
     }
}
private DateTime recruitmentDate;    
public DateTime RecruitmentDate
{
    get { return recruitmentDate; }
    set
    {
        validate(value);
        recruitmentDate = value;
    }
}

如果你的意思是你可以在C#中獲取/設置屬性期間執行自定義邏輯,答案是肯定的。

您使用所謂的自動屬性,其中后備存儲和邏輯默認為您。

你只需要自己提供就好

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

現在,您可以在get和set塊中運行自定義驗證代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM