C# 在属性中声明变量被认为是不好的做法吗?

C# 在属性中声明变量被认为是不好的做法吗?,c#,nhibernate,C#,Nhibernate,我有以下课程: 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 =

我有以下课程:

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;
     }
   }
}
public class PeopleInfo
{
公共虚拟整数ID{get;protected set;}
公共虚拟人Person1{get;set;}
公共虚拟人Person2{get;set;}
公共虚拟人列表
{
得到
{
var p=新列表();
p、 增加(第1人);
p、 添加(第2人);
返回p;
}
}
}

我用的是NHibernate。
Person
类被用作一个组件,因为“PeopleInfo”表的每一行都有一个以上的Person。People()属性背后的思想是提供一个可以循环的只读列表。是否有更好的方法来执行此操作,或者此解决方案是否可以接受?

如果它是只读的,是否需要将其作为列表?您可以将其声明为IEnumerable并执行以下操作:

public virtual IEnumerable<Person> People 
{
    get 
    {
         yield return Person1;
         yield return Person2;
    }
}
公共虚拟人数
{
得到
{
收益回报人1;
收益回报人2;
}
}

按照惯例,通常假定属性立即返回。语义上,它们被用来表示对象的某种“状态”

您当然不应该在属性中执行任何长时间的计算。因此,声明变量是否合适在很大程度上取决于上下文。一般来说,它没有问题,但由于其计算强度,可能不建议动态生成列表

MSDN还有一个有用的页面,供开发人员考虑使用。换言之

通常,方法表示动作,属性表示数据


它没有问题,但是您的示例将在每次get时返回一个新实例。我不确定这是否是您想要的。

声明局部变量是可以的。但是,有一种方法可以缩短代码:

public virtual List<Person> People
{
    get
    {
        return new List<Person> { Person1, Person2 };
    }
}
公共虚拟人列表
{
得到
{
返回新列表{Person1,Person2};
}
}
有没有更好的方法来实现这一点,或者这个解决方案被认为是可以接受的

是的,有一个更好的方法:把它做好

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);
    }
}
People属性背后的想法是提供一个可循环的只读列表。有没有更好的方法来实现这一点,或者这个解决方案被认为是可以接受的

如果这是你的意图,那么你还没有实现它;您提供了一个可以循环的可变列表

幸运的是,您每次都提供不同的可变列表,但您仍然提供可变列表

我倾向于提供一个不变的列表。有很多方法可以做到这一点。如果您确实提供了一个不可变列表,那么您还有一个额外的好处,即可以延迟计算列表,然后缓存并无限期地重复使用,而不是在每次请求时重新构建列表

如果您需要索引访问,那么我将创建一个ReadOnlyCollection,并将其环绕在列表的单个实例上,然后缓存并重新使用只读集合。请注意,如果您改变基础列表,只读集合将出现变化;它只是一个只读列表,而不是一个不变的列表


如果您不需要索引访问,那么我将通过返回
IEnumerable
而不是
List
来表明这一点。然后,您可以返回您选择的任何不可变集合。

请不要在标题前加上“C”。这就是标记的作用。我看不出这样的东西有什么错,只是确保不要在get/set方法中抛出异常。@asawyer:Exception
ObjectDisposedException
,也就是说。感谢您的反馈,您有其他解决方案可以产生相同的结果吗?如果可能的话,我希望能和每个
人见面
@newkid91:我不确定你的确切情况。是否只有两个单独的
Person
对象?如果只有两个,则只需将任何逻辑重构为一个方法,该方法接受
Person
参数,并在两个
Person
对象上调用它。我的最爱!“产量”是惊人的。一个选项是实现IEnumerable。您不能对属性使用
readonly
修饰符,只能对字段使用。这很好地解决了标题中的问题:-P然而,OP可以更清楚地知道他在问什么也许。。。
PeopleInfo (Id PK)
Person (Id PK, Name, PeopleInfoId FK PeopleInfo.Id)