公共领域很少是个好主意?

时间:2012-11-02 16:05:26

标签: c# .net-3.5

显然,公共字段很少是一个好主意,并且不会对属性添加任何内容。

例如:

public class ClientGroupDetails
{
    public DateTime Col2;
    public String Col3;
    public Int32 Col4;

    public ClientGroupDetails(DateTime m_Col2, String m_Col3, Int32 m_Col4)
    {
        Col2 = m_Col2;
        Col3 = m_Col3;
        Col4 = m_Col4;
    }

    public ClientGroupDetails() { }
}

[WebMethod()]
public List<ClientGroupDetails> GetClientGroupDetails(string phrase)
{
    var client_group_details = new List<ClientGroupDetails>();

    using (connection = new SqlConnection(ConfigurationManager.AppSettings["connString"]))
    {
        using (command = new SqlCommand(@"select col2, col3, col4 from table1 where col1 = @strSearch", connection))
        {
            command.Parameters.Add("@strSearch", SqlDbType.VarChar, 255).Value = phrase;

            connection.Open();
            using (reader = command.ExecuteReader())
            {
                int Col2Index = reader.GetOrdinal("col2");
                int Col3Index = reader.GetOrdinal("col3");
                int Col4Index = reader.GetOrdinal("col4");

                while (reader.Read())
                {
                    client_group_details.Add(new ClientGroupDetails(
                        reader.IsDBNull(Col2Index) ? (Nullable<DateTime>)null : (Nullable<DateTime>)reader.GetDateTime(Col2Index),
                        reader.IsDBNull(Col3Index) ? null : reader.GetString(Col3Index),
                        reader.GetInt32(Col4Index)));
                }
            }
        }
    }

    return client_group_details;
}
}

我的问题是,如何将使用公共字段的代码转换为属性?

3 个答案:

答案 0 :(得分:11)

最简单的方法就是:

public DateTime Col2 { get; set; }
public String Col3 { get; set; }
public Int32 Col4 { get; set; }

这将使它们成为自动实现的属性而不是字段。

请注意,我不同意你的说法,即#34;公共领域永远不是一个好主意&#34; - 我确实认为他们很少是一个好主意,但是(很少)他们使用它们比公共财产更好。关于公共领域可能何时合适的一些好的论据,我建议阅读Rico Mariani&#34;基于价值的编程的十个问题&#34;,{ {3}}以及questions。他为公共领域提供了强有力的理由,特别是如果没有非法的价值观,并且您希望常见用例包含频繁的变异。

话虽如此,我认为,在您的具体情况下,转换为物业将是有益的。另外,我建议将其转换为具有有意义名称的属性(不是Col2,而是更像Date等)。


编辑以回应评论:

你的全班将成为:

public class ClientGroupDetails
{
    public DateTime Col2 { get; set; }
    public String Col3 { get; set; }
    public Int32 Col4 { get; set; }

    public ClientGroupDetails(DateTime m_Col2, String m_Col3, Int32 m_Col4)
    {
        Col2 = m_Col2;
        Col3 = m_Col3;
        Col4 = m_Col4;
    }

    public ClientGroupDetails() { }
}

但是,我建议将其重新设计为更好的名称,即:

public class ClientGroupDetails
{
    // Not 100% sure what appropriate names should be here
    public DateTime Date { get; set; }
    public String Name { get; set; }
    public Int32 Id { get; set; }

    public ClientGroupDetails(DateTime date, String name, Int32 id)
    {
        this.Date = date;
        this.Name = name;
        this.Id = id;
    }

    // I also wouldn't include this unless you really need it...
    // public ClientGroupDetails() { }
}

请注意,如果您在创建此类后没有编辑这些值,则可以通过以下方式使它们成为公开可见的属性,但不能设置:

    public DateTime Date { get; private set; }
    public String Name { get; private set; }
    public Int32 Id { get; private set; }

这将允许您的类(即:构造函数)设置值,但是类外的任何内容都不允许更改它们。

答案 1 :(得分:2)

您可以使用私钥和公钥来提供对这些变量的访问。完整(非懒惰)的方式是(这里T是一些类类型)

private T myT;
public T MyT
{
    get { return this.myT; }
    set { this.myT = value; }
}

或者对于我们懒惰的人,你可以使用

public T MyT { get; set; }

我希望这会有所帮助。

答案 2 :(得分:1)

以下是属性语法的示例。在getset块中,您现在可以像函数一样执行代码,因此您可以在将值分配给私有变量之前验证该值。您还可以从get块返回计算值,而不仅仅是公开私有值。

private MyType _myField;

public MyType MyField
{
    get { return _myField; }
    set { _myField = value; }
}

如果您只是隐藏私人会员,还有速记:

public MyType MyField { get; set; }