我无法理解C#语言中getter和setter 的概念。在像Objective-C这样的语言中,它们似乎是系统中不可或缺的一部分,但在C#中并不是那么多(据我所知)。我已经阅读过书籍和文章,所以我的问题是,对于那些了解读者和文章的人。 C#中的setters,如果你将这个概念教给一个完整的初学者,你会亲自使用什么样的例子(这将包括尽可能少的代码行)?
答案 0 :(得分:59)
我认为一些代码将有助于说明setter和getter是什么:
public class Foo
{
private string bar;
public string GetBar()
{
return bar;
}
public void SetBar(string value)
{
bar = value;
}
}
在这个例子中,我们有一个名为bar的类的私有成员。 GetBar和SetBar方法完全按照它们的名称执行 - 一个检索bar成员,另一个设置其值。
在c#1.1 +中你有属性。基本功能也是一样的:
public class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
私人会员栏在课堂外无法访问。然而,公共“Bar”是,它有两个访问器 - get,就像上面的例子“GetBar()”返回私有成员一样,还有一个set - 它对应于前面提到的SetBar(字符串值)方法示例
从C#3.0及更高版本开始,编译器变得优化,以至于此类属性不需要将私有成员作为其源。编译器自动生成该类型的私有成员,并将其用作属性的源。
public class Foo
{
public string Bar { get; set; }
}
代码显示的是一个自动属性,它具有由编译器生成的私有成员。你没有看到私人会员,但它在那里。这也引入了一些其他问题 - 主要是访问控制。在C#1.1和2.0中,您可以省略属性的get或set部分:
public class Foo
{
private string bar;
public string Bar
{
get{ return bar; }
}
}
让您有机会限制其他对象与Foo类的“Bar”属性的交互方式。从C#3.0及更高版本开始 - 如果选择使用自动属性,则必须按如下方式指定对属性的访问权限:
public class Foo
{
public string Bar { get; private set; }
}
这意味着只有类本身可以将Bar设置为某个值,但是任何人都可以读取Bar中的值。
答案 1 :(得分:20)
在C#中,Properties代表您的Getters和Setters。
以下是一个例子:
public class PropertyExample
{
private int myIntField = 0;
public int MyInt
{
// This is your getter.
// it uses the accessibility of the property (public)
get
{
return myIntField;
}
// this is your setter
// Note: you can specify different accessibility
// for your getter and setter.
protected set
{
// You can put logic into your getters and setters
// since they actually map to functions behind the scenes
DoSomeValidation(value)
{
// The input of the setter is always called "value"
// and is of the same type as your property definition
myIntField = value;
}
}
}
}
您可以像字段一样访问此属性。例如:
PropertyExample example = new PropertyExample();
example.MyInt = 4; // sets myIntField to 4
Console.WriteLine( example.MyInt ); // prints 4
其他一些注意事项:
答案 2 :(得分:14)
大多数语言都是这样做的,你也可以用C#来做。
public void setRAM(int RAM)
{
this.RAM = RAM;
}
public int getRAM()
{
return this.RAM;
}
但是C#也为此提供了更优雅的解决方案:
public class Computer
{
int ram;
public int RAM
{
get
{
return ram;
}
set
{
ram = value; // value is a reserved word and it is a variable that holds the input that is given to ram ( like in the example below )
}
}
}
稍后使用。
访问它 Computer comp = new Computer();
comp.RAM = 1024;
int var = comp.RAM;
对于较新版本的C#,它甚至更好:
public class Computer
{
public int RAM { get; set; }
}
以后:
Computer comp = new Computer();
comp.RAM = 1024;
int var = comp.RAM;
答案 3 :(得分:7)
我的解释如下。 (它不是那么短,但它很简单。)
想象一个带有变量的类:
class Something
{
int weight;
// and other methods, of course, not shown here
}
嗯,这个课程有一个小问题:没有人能看到weight
。我们可以公开weight
,但每个人随时都可以更改weight
(这可能不是我们想要的)。所以,我们可以做一个功能:
class Something
{
int weight;
public int GetWeight() { return weight; }
// and other methods
}
这已经更好了,但现在每个人而不是简单的something.Weight
都必须输入something.GetWeight()
,这很丑陋。
对于属性,我们也可以这样做,但代码保持干净:
class Something
{
public int weight { get; private set; }
// and other methods
}
int w = something.weight // works!
something.weight = x; // doesn't even compile
很好,所以使用这些属性我们可以更好地控制变量访问。
另一个问题:好吧,我们希望外部代码能够设置weight
,但是我们想要控制它的值,而不是允许权重低于100.此外,还有其他一些内部变量density
,取决于weight
,所以我们想在density
更改后立即重新计算weight
。
传统上通过以下方式实现:
class Something
{
int weight;
public int SetWeight(int w)
{
if (w < 100)
throw new ArgumentException("weight too small");
weight = w;
RecalculateDensity();
}
// and other methods
}
something.SetWeight(anotherSomething.GetWeight() + 1);
但同样,我们不希望向我们的客户透露设置权重是一项复杂的操作,它在语义上只是分配一个新的权重。所以带有setter的代码看起来一样,但更好:
class Something
{
private int _w;
public int Weight
{
get { return _w; }
set
{
if (value < 100)
throw new ArgumentException("weight too small");
_w = value;
RecalculateDensity();
}
}
// and other methods
}
something.Weight = otherSomething.Weight + 1; // much cleaner, right?
所以,毫无疑问,属性“仅仅”是一种语法糖。但它使客户的代码更好。有趣的是,对类似属性的事物的需求经常出现,你可以检查你在其他语言中找到像GetXXX()和SetXXX()这样的函数的频率。
答案 4 :(得分:4)
C#引入了为您完成大部分繁重任务的属性......
即
public string Name { get; set; }
是写作的C#快捷方式......
private string _name;
public string getName { return _name; }
public void setName(string value) { _name = value; }
基本上,getter和setter只是帮助封装的手段。当你创建一个类时,你有几个类变量可能你想要暴露给其他类,以允许它们一瞥你存储的一些数据。虽然开始公开变量似乎是一种可接受的选择,但从长远来看,你会后悔让其他类直接操作你的类成员变量。如果你强迫他们通过setter来做,你可以添加逻辑以确保不会发生任何奇怪的值,并且你可以在将来改变那个逻辑而不会影响已经操纵这个类的东西。
即
private string _name;
public string getName { return _name; }
public void setName(string value)
{
//Don't want things setting my Name to null
if (value == null)
{
throw new InvalidInputException();
}
_name = value;
}
答案 5 :(得分:2)
这里是实际用例中getter setter的常用用法,
public class OrderItem
{
public int Id {get;set;}
public int quantity {get;set;}
public int Price {get;set;}
public int TotalAmount {get {return this.quantity *this.Price;}set;}
}
答案 6 :(得分:1)
简单示例
public class Simple
{
public int Propery { get; set; }
}
答案 7 :(得分:1)
据我所知,getter和setter都是为了改进封装。 C#中没有任何复杂的东西。
您可以像这样定义对象的属性:
int m_colorValue = 0;
public int Color
{
set { m_colorValue = value; }
get { return m_colorValue; }
}
这是最简单的用法。它基本上设置内部变量或检索其值。 你使用这样的属性:
someObject.Color = 222; // sets a color 222
int color = someObject.Color // gets the color of the object
你最终可以像这样对setter或getter中的值进行一些处理:
public int Color
{
set { m_colorValue = value + 5; }
get { return m_colorValue - 30; }
}
如果您跳过设置或获取,您的财产将只读或写。这就是我理解这些东西的方式。
答案 8 :(得分:0)
这将是使用尽可能少的代码在C#中获取/设置。你得到auto-implemented properties in C# 3.0+。
public class Contact
{
public string Name { get; set; }
}
答案 9 :(得分:0)
在内部,getter和setter只是方法。当C#编译时,它为你的getter和setter生成方法,例如:
public int get_MyProperty() { ... }
public void set_MyProperty(int value) { ... }
C#允许您使用简写语法声明这些方法。在构建应用程序时,下面的行将被编译到上面的方法中。
public int MyProperty { get; set; }
或
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; } // value is an implicit parameter containing the value being assigned to the property.
}
答案 10 :(得分:0)
C#中的Getters和Setter简化了代码。
private string name = "spots";
public string Name
{
get { return name; }
set { name = value; }
}
并调用它(假设我们有一个名为obj的人物):
Console.WriteLine(Person.Name); //prints "spots"
Person.Name = "stops";
Console.Writeline(Person.Name); //prints "stops"
这简化了您的代码。在Java中,你可能必须有两个方法,一个是Get(),一个是Set()属性,在C#中,它们都在一个地方完成。我通常在课程开始时这样做:
public string foobar {get; set;}
这为我的foobar属性创建了一个getter和setter。调用它与之前显示的方式相同。需要注意的事项是,您不必同时包含get和set。如果您不希望修改属性,请不要包含set!
答案 11 :(得分:0)
这是带有getter和setter的对象“Article”的基本示例:
public class Article
{
public String title;
public String link;
public String description;
public string getTitle()
{
return title;
}
public void setTitle(string value)
{
title = value;
}
public string getLink()
{
return link;
}
public void setLink(string value)
{
link = value;
}
public string getDescription()
{
return description;
}
public void setDescription(string value)
{
description = value;
}
}