簡體   English   中英

在屬性中聲明變量被認為是不好的做法嗎?

[英]Is it considered bad practice to declare variables within a property?

我有以下課程:

public class PeopleInfo
{
   public virtual int ID {get; protected set;}
   public virtual Person Person1 {get;set;}
   public virtual Person Person2 {get;set;}

   public virtual List<Person> People
   {
     get
     {
        var p = new List<Person>();
        p.Add(Person1);
        p.Add(Person2);
        return p;
     }
   }
}

我正在使用NHibernate。 Person類被用作組件,因為“PeopleInfo”表在每行中有超過1個人。 People()屬性背后的想法是提供一個可以循環的只讀列表。 有沒有更好的方法來做到這一點,還是認為這個解決方案可以接受?

People屬性背后的想法是提供一個可以循環的只讀列表。 有沒有更好的方法來做到這一點,還是認為這個解決方案可以接受?

如果這是你的意圖那么你還沒有實現它; 你提供了一個可以循環的可變列表

幸運的是,每次都提供不同的可變列表,但您仍然提供可變列表。

我傾向於實際提供一個不可變的列表。 有很多方法可以做到這一點。 如果您實際提供了一個不可變列表,那么您還可以獲得額外的好處,即可以懶惰地計算列表,然后無限期地緩存和重新使用,而不是每次請求時重新構建。

如果您需要索引訪問,那么我將創建一個ReadOnlyCollection並將其包裝在列表的單個實例周圍,然后緩存並重新使用只讀集合。 請注意,如果您改變基礎列表,則只讀集合將顯示為mutate; 它只是一個只讀列表,它不是一個不可變列表。

如果您不需要索引訪問,那么我會通過返回IEnumerable<T>而不是List<T>來指示。 然后,您可以返回您選擇的任何不可變集合。

如果它是re​​adonly,你需要它作為一個列表嗎? 你可以將它聲明為IEnumerable並執行:

public virtual IEnumerable<Person> People 
{
    get 
    {
         yield return Person1;
         yield return Person2;
    }
}

按慣例,通常假定屬性立即返回。 從語義上講,它們用於表示對象的某種“狀態”。

你當然不應該在屬性中進行任何長時間的計算。 因此,它在很大程度上取決於上下文是否適合聲明變量。 一般來說,它沒有問題,但由於其計算強度,可能建議動態生成列表。

對於考慮使用Properties vs. Methods的開發人員,MSDN也有一個有用的頁面。 換句話說,

通常,方法表示動作,屬性表示數據。

有沒有更好的方法來做到這一點,還是認為這個解決方案可以接受?

是的,有一種更好的方法:做得對。

public class PeopleInfo {
    public virtual int Id { get; set; }
    public virtual IList<Person> People { get; set; }
}

public class Person {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual PeopleInfo PeopleInfo { get; set; }
}

public class PeopleInfoMap : ClassMap<PeopleInfo> {
    public PeopleInfoMap() {
        Id(x => x.Id);
        HasMany(x => x.People)
            .Cascade.None()
            .Inverse();
    }
}

public class PersonMap : ClassMap<Person> {
    public PersonMap() {
        Id(x => x.Id);
        Map(x => x.Name);
        References(x => x.PeopleInfo);
    }
}

您的數據庫表應如下所示:

PeopleInfo (Id PK)
Person (Id PK, Name, PeopleInfoId FK PeopleInfo.Id)

它沒有錯,但是你的例子將返回每個get的新實例。 我不確定這是不是你想要的。

聲明局部變量很好。 但是,有一種方法可以縮短您的代碼:

public virtual List<Person> People
{
    get
    {
        return new List<Person> { Person1, Person2 };
    }
}

暫無
暫無

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

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