属性私人集;

时间:2010-03-02 19:30:29

标签: c# properties

我知道它只允许班级设置它,但重点是什么?

如何解决只读ID的问题?

说我有一个人班:

public class Person
    {
        public string Name { get;  set; }
        public int Id { get; private set; }
        public int Age { get; set; }
    }

这是Entities.dll,由GUI,BL和DAL使用。

GUI调用BL:

   List<Person> p =  BL.PeopleBL.GetPeople();

为了示例,请调用DAL:

...
while(dr.read())
{
    returnPersonList.add( new Person{ Age=dr.GetInt32(1), Id=dr.GetInt32(0), Name=dr.GetString(2)})
}
...

当然我不能这样做因为Id是私人套装; 这样做的正确方法是什么?

如何让BL / Dal设置Id,而不是GUI?

或者这甚至不能正确使用私人套装?


我只想补充一点,这是典型的数据库应用程序,其中pk是Id,不应更改(仅限BL / DAL)


9 个答案:

答案 0 :(得分:36)

这是一种可能的解决方案,虽然不是很干净:

  1. 将您需要的属性暴露给BAL&amp; DAL internal
  2. 标记BAL.dll&amp; DAL.dll
  3. 中的assemblyinfo.cs 内部可见

    public class Person
    {
        public Person(int id)
        {
             this.Id=id;
        }
    
        public string Name { get;  set; }
        public int Id { get; internal set; }
        public int Age { get; set; }
    }
    
    AssemblyInfo.cs

    Entities.dll

    [assembly: InternalsVisibleTo("DAL"), InternalsVisibleTo("BAL")]
    

    这样,DAL&amp; amp; BAL。这可能不太理想,但我只是建议一种可能的解决方案。

答案 1 :(得分:18)

两种常见的方法是该类应具有DAL要使用的构造函数,或者DAL应使用反射来水合对象。

答案 2 :(得分:12)

或者你可以做到

public class Person
{
    public Person(int id)
    {
         this.Id=id;
    }

    public string Name { get;  set; }
    public int Id { get; private set; }
    public int Age { get; set; }
}

答案 3 :(得分:9)

也许我误解了,但如果你真的想要读书,那么为什么不使用实际的只读字段呢?

public class Person
{
   public Person(int id)
   {
      m_id = id;
   }

   readonly int m_id;
   public int Id { get { return m_id; } }
}

答案 4 :(得分:7)

您可以通过构造函数提供用户设置只读属性:

public class Person
{
    public Person(int id)
    {
        this.Id = id;
    }

    public string Name { get;  set; }
    public int Id { get; private set; }
    public int Age { get; set; }
}

答案 5 :(得分:2)

while(dr.read())
{
    returnPersonList.add( 
        new Person(dr.GetInt32(1), dr.GetInt32(0), dr.GetString(2)));
}

其中:

public class Person
{
    public Person(int age, int id, string name) 
    {
        Age = age;
        Id = id;
        Name = name;
    }
}

答案 6 :(得分:2)

也许,您可以将它们标记为内部,在这种情况下,只有DAL或BL中的类(假设它们是独立的dll)才能设置它。

您还可以提供一个构造函数来获取字段,然后只将它们公开为属性。

答案 7 :(得分:1)

通常情况下,ID不是实体的自然部分,而是需要抽象出来的数据库工件。

这是一个设计决策 - 只允许在构造期间或通过方法调用设置ID,因此它由类内部管理。

假设您有一个支持字段,您可以自己编写一个setter:

private int Id = 0;
public void SetId (int id)
{
  this.Id = id;
}

或通过构造函数:

private int Id = 0;
public Person (int id)
{
  this.Id = id;
}

答案 8 :(得分:0)

根据我的应用范围,我喜欢将对象水化机制放在对象本身中。我将使用自定义对象包装数据读取器,并向其传递一个在查询返回后执行的委托。委托传递给DataReader。然后,因为我是我聪明的商业对象,我可以用我的私人制定者来保湿。

编辑伪代码

“DataAccessWrapper”为我包装了所有连接和对象生命周期管理。因此,当我调用“ExecuteDataReader”时,它会创建连接,传递的proc(对于params有一个重载)执行它,执行委托然后自行清理。

public class User
{
    public static List<User> GetAllUsers()
    {
        DataAccessWrapper daw = new DataAccessWrapper();
        return (List<User>)(daw.ExecuteDataReader("MyProc", new ReaderDelegate(ReadList)));
    }

    protected static object ReadList(SQLDataReader dr)
    {
        List<User> retVal = new List<User>();
        while(dr.Read())
        {
            User temp = new User();
            temp.Prop1 = dr.GetString("Prop1");
            temp.Prop2 = dr.GetInt("Prop2");
            retVal.Add(temp);
        }
        return retVal;
    }
}