C# getter和setter与类方法

C# getter和setter与类方法,c#,getter-setter,C#,Getter Setter,我想问一下关于使用getter和setter的建议。 我在两个版本中编写了相同的代码:使用getter和setter以及仅使用class方法。我看不清它们之间的区别 我写了一本有私人领域评分的教材。构造函数Book可以通过RatingSetter或RatingMethod为Book.rating分配一些内容。 RatingMethod只设置值,但我也可以创建一个仅用于获取值的方法 class Book { public string title; publ

我想问一下关于使用getter和setter的建议。 我在两个版本中编写了相同的代码:使用getter和setter以及仅使用class方法。我看不清它们之间的区别

我写了一本有私人领域评分的教材。构造函数Book可以通过RatingSetter或RatingMethod为Book.rating分配一些内容。 RatingMethod只设置值,但我也可以创建一个仅用于获取值的方法

class Book
    {
        public string title;
        public string author;
        private string rating;

        public Book(string title, string author, string rating)
        {
            this.title = title;
            this.author = author;
            RatingSetter = rating;
            RatingMethod(rating);
        }

        public string RatingSetter
        {
            get { return this.rating; }
            set
            {
                if (value == "PG" || value == "PG-13" || value == "R")
                {
                    rating = value;
                }
                else
                {
                    rating = "NR";
                }
            }
        }

        public string RatingMethod(string rating)
        {
            if (rating == "PG" || rating == "PG-13" || rating == "R")
            {
                return this.rating = rating;
            }
            else
            {
                return this.rating = "NR";
            }
        }
    }
在我看来,在安全性、验证或其他方面没有区别。
有没有人能指导并帮助我理解两者的区别,以及为什么建议使用getter和setter

功能是相同的。但它使代码更加可读和易懂

在您的示例中,通过调用
RatingSetter
RatingMethod
验证
rating
。考虑你在团队中工作,你的同事不知道验证方法,简单地调用<代码>这个。以你的例子来说,不会有任何验证。我的代码示例(未测试)确保对每个赋值都进行验证

private string rating {
     get { return this.rating; }
        set
        {
            if (value == "PG" || value == "PG-13" || value == "R")
            {
                rating = value;
            }
            else
            {
                throw new UnknownRatingException();

            }
        }
}

public Book(string title, string author, string rating)
    {
        this.title = title;
        this.author = author;
        this.rating = rating //the set property is called
    }

getter和setter只是语法糖。编译器最终将把getter和setter编译成getter和setter方法。因此,通过自己编写getter和setter方法,您就完成了编译器的工作

因此,我建议您使用getter和setter,因为它们的主要用途之一是替换getter和setter方法

下面是使用getter和setter的一些其他优点:

  • 如果您只需要getter和setter而不需要任何逻辑,那么getter和setter可以为您节省大量时间:

    public int Property { get; set; }
    
  • 在我看来,能手和二传手的美感看起来更好。比较:

    obj1.Property += obj2.Property;
    

    我觉得后者的括号太多了

  • 使setter和getter靠近属性声明。如果使用getter和setter方法,可能会意外地在属性声明和getter/setter方法之间编写其他方法,从而导致getter/setter方法慢慢地“偏离”属性声明。下次你想找到它时,你需要上下滚动。使用getter和setter时,它们将始终位于属性声明的下方

来自

属性是提供灵活机制来读取、写入或计算私有字段值的成员

这基本上就是他们所说的属性是专门构建的成员,它的存在仅仅是为了包装和访问私有成员,使得“数据可以轻松访问,并且仍然有助于提高方法的安全性和灵活性。”

在您的示例中,我将
RatingSetter
重命名为
Rating
,并将其视为一个普通的公共字段。这提高了易用性,并减少了其他人使用您的代码时的混乱。更明显的是,你正在做什么和需要做什么

也不建议使用公共字段,例如
公共字符串标题
相反,通常最好选择使用属性包装此字段并使其私有,例如

private string title;
public string Title {get; set;}
然后,您可以在类之外使用公共属性,但现在可以更好地控制当有人访问或设置变量时会发生什么

private string title;
public string Title {get; private set;}
这将只允许从类外部进行读取访问

日志记录现在更容易了,因为您可以在setter中实现它:

private string title;
public string Title 
{
    get{ return title;}
    set
    {
        // Logging Code Here
        title = value;
    }
}

总之,属性是简洁的,功能是显而易见的,就像字段一样,但具有方法的所有功能和灵活性。

它们在内部做同样的事情。区别在于你如何使用它们的语义。我不同意评论和回答@Crowcoder:you link文章的第一句话是:
“值得一提的是,这篇文章没有讨论什么东西应该是一个方法还是一个属性的问题。”
这正是上面问题中要问的。因此,如果你所引用的文章没有明确提到这个问题,你到底在建议什么?@David我不是这样解释这个问题的,但我明白你的意思。我更笼统地看待它,而不是“这个特定的东西应该是一种属性还是一种方法?”@David有趣的是,这被标记为Jon Skeet回答的一个更一般的最佳实践问题的复制品。你投票重新开放吗?为什么它更容易阅读和理解?你能给出两种解释方法吗?我会在
else
子句中使用
抛出新的UnknownRatingException()
,以显示一个很好的特定用例。你的答案越来越糟。你的最后一段没有回答这个问题,只是把事情弄糊涂了。问题是为什么一种方法比另一种更可取。这与方法的必要性无关。我的例子展示了如何通过使用setter和getter来减少代码。因此,您可以去掉一些额外的方法。我没有写它绝对安全,我写它更安全。@AlinaJ-不,它没有。您需要展示编写代码的两种方法,然后讨论它们之间的差异。此外,与方法相比,属性验证没有任何好处。为什么更灵活?为什么更连贯?比标准公共字段更灵活,因为您可以选择在属性体中添加更多功能。更连贯,因为它更明显地模拟访问和写入属性。@Enigmativity,因为您可以记录对getter/setter的访问。可以在获取/设置值之前对其进行转换。例如,
Minute{get}
Hour{get}
只存储一个计算值。您可以提供对其他字段属性的访问
int-ProductId=>\u-product.Id
。您只能允许设置o
private string title;
public string Title 
{
    get{ return title;}
    set
    {
        // Logging Code Here
        title = value;
    }
}