以前是学C++的,初次学微软的C#头都大了。什么字段,常量,属性,方法......微软把别人的东西拿来糅合在C#里,弄成了一个“大杂烩”。其实,说到底,“字段”不就是“变量”吗,所谓的“方法”不就是“函数”吗,故弄玄虚!从MSDN上弄来了详细的介绍,看下面:

字段:

“字段”是直接在结构中声明的任何类型的变量。 字段是其包含类型的“成员”。

类或结构可以拥有实例字段或静态字段,或同时拥有两者。 实例字段特定于类型的实例。 如果您拥有类 T 和实例字段 F,可以创建类型 T 的两个对象,并修改每个对象中 F 的值,这不影响另一对象中的该值。 相比之下,静态字段属于类本身,在该类的所有实例中共享。 从实例 A 所做的更改将立刻呈现在实例 B 和 C 上(如果它们访问该字段)。

通常应仅为具有私有或受保护可访问性的变量使用字段。 您的类向客户端代码公开的数据应通过方法属性索引器提供。 通过使用这些构造间接访问内部字段,可以针对无效的输入值提供防护。 存储由公共属性公开的数据的私有字段称为“后备存储”或“支持字段”。

字段通常存储这样的数据:该数据必须可供多个类方法访问,并且其存储期必须长于任何单个方法的生存期。 例如,表示日历日期的类可能有三个整数字段:一个表示月份,一个表示日期,还有一个表示年份。 不在单个方法范围外部使用的变量应在方法体自身范围内声明为局部变量。

在类块中通过指定字段的访问级别,然后指定字段的类型,再指定字段的名称来声明这些字段。 例如:

 public class CalendarEntry
{
// private field
private DateTime date; // public field (Generally not recommended.)
public string day; // Public property exposes date field safely.
public DateTime Date
{
get
{
return date;
}
set
{
// Set some reasonable boundaries for likely birth dates.
if (value.Year > && value.Year <= DateTime.Today.Year)
{
date = value;
}
else
throw new ArgumentOutOfRangeException();
} } // Public method also exposes date field safely.
// Example call: birthday.SetDate("1975, 6, 30");
public void SetDate(string dateString)
{
DateTime dt = Convert.ToDateTime(dateString); // Set some reasonable boundaries for likely birth dates.
if (dt.Year > && dt.Year <= DateTime.Today.Year)
{
date = dt;
}
else
throw new ArgumentOutOfRangeException();
} public TimeSpan GetTimeSpan(string dateString)
{
DateTime dt = Convert.ToDateTime(dateString); if (dt != null && dt.Ticks < date.Ticks)
{
return date - dt;
}
else
throw new ArgumentOutOfRangeException(); }
}

若要访问对象中的字段,请在对象名称后面添加一个句点,然后添加该字段的名称,比如 objectname.fieldname。 例如:

 CalendarEntry birthday = new CalendarEntry();
birthday.day = "Saturday";

声明字段时可以使用赋值运算符为字段指定一个初始值。 例如,若要自动将 "Monday" 赋给 day 字段,需要声明 day,如下例所示:

public class CalendarDateWithInitialization
{
public string day = "Monday";
//...
}

字段的初始化紧靠调用对象实例的构造函数之前。 如果构造函数为字段赋值,则该值将覆盖字段声明期间给出的任何值。

字段可标记为 publicprivateprotectedinternal 或 protected internal。 这些访问修饰符定义类的使用者访问字段的方式。 有关更多信息,请参见 访问修饰符(C# 编程指南)

可以选择将字段声明为 static。 这使得调用方在任何时候都能使用字段,即使类没有任何实例。 有关更多信息,请参见 静态类和静态类成员(C# 编程指南)

可以将字段声明为 readonly。 只读字段只能在初始化期间或在构造函数中赋值。 static readonly 字段非常类似于常数,只不过 C# 编译器不能在编译时访问静态只读字段的值,而只能在运行时访问。 有关更多信息,请参见 常量(C# 编程指南)

常量:

常量是在编译时已知并在程序的生存期内不发生更改的不可变值。 常量使用 const 修饰符进行声明。 只有 C# 内置类型(System.Object 除外)可以声明为 const。 有关内置类型的列表,请参见内置类型表(C# 参考)。 用户定义的类型(包括类、结构和数组)不能为 const。 请使用 readonly 修饰符创建在运行时初始化一次即不可再更改的类、结构或数组。

C# 不支持 const 方法、属性或事件。

可以使用枚举类型为整数内置类型(例如 int、uint、long 等等)定义命名常量。 有关更多信息,请参见 enum(C# 参考)

常量必须在声明时初始化。 例如:

 class Calendar1
{
public const int months = ;
}

在此示例中,常量 months 始终为 12,不可更改,即使是该类自身也不能更改它。 实际上,当编译器遇到 C# 源代码(例如 months)中的常量修饰符时,将直接把文本值替换到它生成的中间语言 (IL) 代码中。 因为在运行时没有与常量关联的变量地址,所以 const 字段不能通过引用传递,并且不能在表达式中作为左值出现。

可以同时声明多个相同类型的常量,例如:

class Calendar2
{
const int months = , weeks = , days = ;
}

如果不会造成循环引用,用于初始化一个常量的表达式可以引用另一个常量。 例如:

 class Calendar3
{
const int months = ;
const int weeks = ;
const int days = ; const double daysPerWeek = (double) days / (double) weeks;
const double daysPerMonth = (double) days / (double) months;
}

常量可标记为 publicprivateprotectedinternal 或 protectedinternal。 这些访问修饰符定义类的用户访问该常量的方式。 有关更多信息,请参见 访问修饰符(C# 编程指南)

因为常量值对该类型的所有实例是相同的,所以常量被当作 static 字段一样访问。 不使用 static 关键字声明常量。 未包含在定义常量的类中的表达式必须使用类名、一个句点和常量名来访问该常量。 例如:

int birthstones = Calendar.months;

属性:

属性是这样的成员:它提供灵活的机制来读取、编写或计算某个私有字段的值。 可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。 这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。

在本示例中,TimePeriod 类存储一个时间段。 在内部,类以秒为单位存储时间,但客户端使用名为 Hours 的属性能够以小时为单位指定时间。 Hours 属性的访问器执行小时和秒之间的转换。

 class TimePeriod
{
private double seconds; public double Hours
{
get { return seconds / ; }
set { seconds = value * ; }
}
} class Program
{
static void Main()
{
TimePeriod t = new TimePeriod(); // Assigning the Hours property causes the 'set' accessor to be called.
t.Hours = ; // Evaluating the Hours property causes the 'get' accessor to be called.
System.Console.WriteLine("Time in hours: " + t.Hours);
}
}
// Output: Time in hours: 24
  • 属性使类能够以一种公开的方法获取和设置值,同时隐藏实现或验证代码。

  • get 属性访问器用于返回属性值,而 set 访问器用于分配新值。 这些访问器可以有不同的访问级别。 有关更多信息,请参见 限制访问器可访问性(C# 编程指南)

  • value 关键字用于定义由 set 取值函数分配的值。

  • 不实现 set 取值函数的属性是只读的。

  • 对于不需要任何自定义访问器代码的简单属性,可考虑选择使用自动实现的属性。 有关更多信息,请参见自动实现的属性(C# 编程指南)

方法:

“方法”是包含一系列语句的代码块。 程序通过“调用”方法并指定所需的任何方法参数来执行语句。 在 C# 中,每个执行指令都是在方法的上下文中执行的。 Main 方法是每个 C# 应用程序的入口点,在启动程序时由公共语言运行时 (CLR) 调用。

通过指定方法的访问级别(例如 public 或 private)、可选修饰符(例如 abstract 或 sealed)、返回值、名称和任何方法参数,可以在结构中声明方法。 这些部分统称为方法的“签名”。

方法参数括在括号中,并用逗号隔开。 空括号表示方法不需要参数。 下面的类包含三个方法:

 abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ } // Only derived classes can call this.
protected void AddGas(int gallons) { /* Method statements here */ } // Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* Method statements here */ return ; } // Derived classes must implement this.
public abstract double GetTopSpeed();
}

在对象上调用方法类似于访问字段。 在对象名称之后,依次添加句点、方法名称和括号。 参数在括号内列出,并用逗号隔开。 因此,可以按以下示例中的方式调用 Motorcycle类的方法:

 class TestMotorcycle : Motorcycle
{ public override double GetTopSpeed()
{
return 108.4;
} static void Main()
{ TestMotorcycle moto = new TestMotorcycle(); moto.StartEngine();
moto.AddGas();
moto.Drive(, );
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}

方法定义指定所需任何“形参”的名称和类型。 调用代码在调用方法时,将为每个形参提供称为“实参”的具体值。 实参必须与形参类型兼容,但调用代码中使用的实参名称(如果有)不必与方法中定义的形参名称相同。 例如:

 public void Caller()
{
int numA = ;
// Call with an int variable.
int productA = Square(numA); int numB = ;
// Call with another int variable.
int productB = Square(numB); // Call with an integer literal.
int productC = Square(); // Call with an expression that evaulates to int.
productC = Square(productA * );
} int Square(int i)
{
// Store input argument in a local variable.
int input = i;
return input * input;
}

默认情况下,将值类型传递给方法时,传递的是副本而不是对象本身。 因此,对参数所做的更改对于调用方法中的原始副本没有影响。 可以使用 ref 关键字通过引用传递值类型。 有关更多信息,请参见传递值类型参数(C# 编程指南)。 有关内置值类型的列表,请参见值类型表(C# 参考)

当引用类型的对象传递给方法时,对对象的引用传递。 即方法接收不是对象,还指示对象的位置的参数。 如果更改对象的成员通过使用该引用,更改反映在被调用的方法的参数,因此,即使通过对象的值。

如下面的示例所示,通过使用 class 关键字,则创建一个引用类型。

public class SampleRefType
{
public int value;
}

现在,因此,如果您通过根据方法的此类型的对象,对对象的引用传递。 下面的示例通过类型 SampleRefType 对象传递给方法 ModifyObject。

 public static void TestRefType()
{
SampleRefType rt = new SampleRefType();
rt.value = ;
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = ;
}

该示例实质上执行操作与前例同样因为它通过值传递实参传递给方法。 但,使用引用类型,则结果是不同的。 在对该参数进行 value 字段的 ModifyObject 做的修改,obj,也会更改参数,rt的 value 字段,在 TestRefType 方法。 TestRefType 方法显示 33 作为输出。

方法可以向调用方返回值。 如果返回类型(方法名称前列出的类型)不是 void,则方法可以使用 return 关键字来返回值。 如果语句中 return 关键字的后面是与返回类型匹配的值,则该语句将该值返回给方法调用方。 return 关键字还会停止方法的执行。 如果返回类型为 void,则可使用没有值的 return 语句来停止方法的执行。 如果没有return 关键字,方法执行到代码块末尾时即会停止。 具有非 void 返回类型的方法才能使用 return 关键字返回值。 例如,下面的两个方法使用 return 关键字来返回整数:

 class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
} public int SquareANumber(int number)
{
return number * number;
}
}

C#中的字段,常量,属性与方法的更多相关文章

  1. C#类中的字段、属性和方法

    C#类中的字段.属性和方法 刚开始学C#,对于类中的字段.属性和方法很难分清,写下这份笔记,帮助理解 字段:与类相关的变量 声明方法与声明变量类似,可在前面添加访问修饰符.static关键字等: 属性 ...

  2. C#反射类中所有字段,属性,方法

    可能大家都知道在C#中如何创建一个类,但对于类的结构可能大家不一定了解的很清楚,对于我来说,我之前也搞的不是很明白,今天,当我没事研究反射的时候突然发现了着一点.我们来看类的结构到底是什么 publi ...

  3. C#中全局作用域的常量、字段、属性、方法的定义与使用

    场景 在开发中,经常会有一些全局作用域的常量.字段.属性.方法等. 需要将这些设置为全局作用域保存且其实例唯一. 注: 博客主页: https://blog.csdn.net/badao_liuman ...

  4. IL角度理解C#中字段,属性与方法的区别

    IL角度理解C#中字段,属性与方法的区别 1.字段,属性与方法的区别 字段的本质是变量,直接在类或者结构体中声明.类或者结构体中会有实例字段,静态字段等(静态字段可实现内存共享功能,比如数学上的pi就 ...

  5. [.net 面向对象编程基础] (10) 类的成员(字段、属性、方法)

    [.net 面向对象编程基础] (10) 类的成员(字段.属性.方法) 前面定义的Person的类,里面的成员包括:字段.属性.方法.事件等,此外,前面说的嵌套类也是类的成员. a.类的成员为分:静态 ...

  6. C#类的成员(字段、属性、方法)

    前面定义的Person的类,里面的成员包括:字段.属性.方法.事件等,此外,前面说的嵌套类也是类的成员. a.类的成员为分:静态成员(static)和非静态成员 b.静态成员用static标识,不标识 ...

  7. C#中的字段与属性的区别及属性的作用

    C#中的字段与属性的区别及属性的作用 先上代码 public class Employee { //字段 private string name; //属性 public string Name { ...

  8. @NamedEntityGraphs --JPA按实体类对象参数中的字段排序问题得解决方法

    JPA按实体类对象参数中的字段排序问题得解决方法@Entity @Table(name="complaints") @NamedEntityGraphs({ @NamedEntit ...

  9. mongoose中给字段添加索引的方法

    mongoose中给字段添加索引的方法有两种,一种通过在定义schema的时候配置,如: var animalSchema = new Schema({ name: String, type: Str ...

  10. HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)

    HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...

随机推荐

  1. 时序数据库连载系列: 时序数据库一哥InfluxDB之存储机制解析

    InfluxDB 的存储机制解析 本文介绍了InfluxDB对于时序数据的存储/索引的设计.由于InfluxDB的集群版已在0.12版就不再开源,因此如无特殊说明,本文的介绍对象都是指 InfluxD ...

  2. Git的基本了解与使用、向github提交代码

    #Git的基本了解与使用.向github提交代码- git:是一个版本控制系统.- github:一个代码托管提供商.开源网站.是一个面向开源及私有软件项目的托管平台,因为支持Git作为唯一的版本库格 ...

  3. Linq 之 Where操作

    适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句. Where操作包括3种形式,分别为简单形式.关系条件形式 ...

  4. 记录centos7下tomcat部署war包过程

    记录centos7下tomcat部署war包过程 1.官网下载tomcat安装包.gz结尾的 2.上传到/usr/local/ ,并解压到tomcat目录下 3.进入tomcat/bin目录,运行./ ...

  5. re模块元字符

    #元字符在re模块中有特殊意义的字符,有:^ $. * + {} [] () | \ ^$ #表示开头结尾,注意:[^]表示取反 . #点,表示任意一个字符,包括空格(一个空白字符),\t(换行符). ...

  6. python_数据类型_list

    names = ['one','two','three','four','five'] #列表切片 print(names[0:]) #['one', 'two', 'three', 'four', ...

  7. 【arc077f】AtCoder Regular Contest 074 F - Lotus Leaves

    题意 给定一个n*m的池塘,每个格子上可能有叶子. 从一个叶子出发,可以跳到相同行或相同列的叶子. 问至少去掉多少叶子,使得起点不能到达终点. \(n,m<=100\) 解法 很显然的最小割模型 ...

  8. 关于python的列表操作(二):排序,统计

    # 列表操作 num_list = [2, 5, 8, 6, 7, 9, 5, 7] # 升序 num_list.sort() print(num_list) # 降序 num_list.sort(r ...

  9. 解决pycharm新建工程项目都需要重新安装库问题

    在新建一个工程项目后,发现之前安装的库均不在了.想要使用的情况下还得重新安装.这样也太不智能了,一定会有解决的办法.查找相关文档后,发现在新建工程项目的时候需要进行选择是否使用以前的环境. 选择已存在 ...

  10. 解决CSDN博客插入代码出现的问题

    我在写CSDN博客的时候有时候会在插入代码之后继续编辑,然后保存之后经常会出现一些多余的符号<p 例如<pre></pre>,这样的标记,其实这是html的一个元素,pr ...