之值类型和引用类型,在类中定义的字段为什么

作者: 编程  发布:2019-11-09

 

  1. C# 中(不同于 C++)的变量,总是需要你在访问它们前先进行初
    始化,否则你将遇到编译时错误。故而,不可能访问未初始化的变量。
  2. 你不能在 C# 中访问一个“挂起”指针。
  3. 超出数组边界的表达式索引值同样不可访问。
  4. C# 中没有全局变量或全局函数,取而代之的是通过静态函数和静态

问题:字段初始值设定项无法引用非静态字段、方法或属性的问题

变量完成的。
C#之值类型和引用类型

下面代码出错的原因,在类中定义的字段为什么不能用? 
public class Test 
{
    public Test()
    {
    }
    public int Age=23;
    public int temp = Age;//ERROR 字段初始值设定项无法引用非静态字段、方法或属性
}

一 、值类型和引用类型 异同

 

值类型引用就会报错,引用类型就不会
值类型没有初始化,就没有在内存开辟空间
值类型 : 所有值类型均隐士派生与System.ValueType;
如:bool****型:bool(System.Boolean的别名);
枚举:enum(派生于System.Enum);
可空类型(派生于System.Nullable泛型结构体,语法 T? 是 System.Nullable<T> 的简写,此处的 T 为值类型。)
**2.每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。
**例如:
int i = new int();
等价于:Int32 i = new Int32();
等价于:int i = 0;
等价于:Int32 i = 0;
使用new运算符时,将调用特定类型的默认构造函数并对变量赋以默认值。在上例中,默认构造函数将值0赋给了i。
3.所有的值类型都是密封(seal)的,所以无法派生出新的值类型。
4.****值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。

C#规定在类内部只能定义属性或者变量,并初始化,不能直接变量引用变量。

引用类型的特性:
1.****C#的所有引用类型均隐式派生自System.object。
****各个引用类型及其基类:
****数组:
(派生于System.Array)数组的元素,不管是引用类型还是值类型,都存储在托管堆上;
类:class(派生于System.Object);
接口:interface(接口不是一个“东西”,所以不存在派生于何处的问题。);
委托:delegate(派生于System.Delegate);
object****:(System.Object的别名);
字符串:string(System.String的别名)。
2.引用类型可以派生出新的类型。
3.引用类型可以包含null值。
4.****引用类型变量的赋值只复制对对象的引用,而不复制对象本身。
5.引用类型的对象总是在进程堆中分配(动态分配)。

在初始化类实例之前就调用了字段

二 、c#没有全局变量,每一个c#文件都不会互相干扰吗?那么一个变量怎么互相引用?

c# 中字段的初始化先于构造函数。

你这说的是什么意思呀。C#怎么会没有全局变量呢,你如果只是不知道怎么可以在不同类之间互想调用变量值这还可以理解。下面是我给你的分类:
全局变量可会为,同类下的全局变量即在一个类里定义
public class class1
{
public int 变量1;
public static int 变量2;
public const int 变量3;

string y = "asdf" + x; 实际上是 y = "asdf" + this.x;

public readonly int 变量4;

因为这时this还没被初始化,所以编译会报错。

}
变量1的调用方法:只能通过class1实例调用。如 class1 test = new class1;
int class变量值 = test.变量1;(注意此时变量值要用关键字public/internal/protecd才可调用)具体这三个关键字的用法你可以去研究下。如是关键字是private 那就不能调用了。但可用变通的做法。可以用属性如可以在类里增加一个属性来控制对变量的调用方式

属性内存和变量内存的分配的时间不一样。 
属性是用的时候分配,变量是在类初始化时候分配。

public int 调用变量1
{
get{return this.变量1;}
private set{this.变量1 = value;}
}
这样你可以把变量1用private关键字封闭起来,不让用户去修改或访问它。如果要知道他的值可以调用属性 int class变量值 = test.调用变量1;获得值。但无法修改这个变量值。除非在属性中的删除set的关键字private 这样才可以在其它类里获取或修改它的值。
变量2的调用方法:这种变量在程序加载之后即运行时。系统就会事先定义此变量。调用方法就是不管在何处都可以对它修改访问 int 变量2值 = class.变量2; 在这里要注意正因为这个变量唯一只有一个不管理你class1创建了多少个实例其变量2的值也只有一份。不会多也不会少。以下的另个变量也是这样的只是其他两种变量不可修改。如果对变量2进行修改的话要注意在多线程的线程冲突。因为此变量只有一份如果其中一个线程正在修改还没有完成而另一个线程确来访问变量值就有可以得到不正确的值。
变量3与变量4的调用方法:与变量2相同只是不能修改。两者唯一不同的是值存放的形式的不同
变量3在编译时是直接将值的给对方的调用方。而变量4是在运行时才把最终的值给调用方。其中利弊可以自己权衡。

三、C#中静态函数的作用
public static void haha()与public void haha()有什么区别~~
class Test
{
public static void A方法()
public voidB方法()
}
在调用的时候,如果我要调用 A方法只需这样调用:Test.A方法()如果要调用B方法这样调用Test ts = new Test();ts.B方法静态方法的好处就是你无需new(也就是实例化)那个Test类.

静态变量使用 static 修饰符进行声明,在类被实例化时创建,通过类进行访问不带有 static 修饰符声明的变量称做非静态变量。
static变量在对象被实例化时创建,通过对象进行访问一个类的所有实例的同一C#静态变量都是同一个值,同一个类的不同实例的同一非静态变量可以是不同的值。
静态函数的实现里不能使用非静态成员,如非静态变量、非静态函数等。
class StaticTest{
static int x = 0; int y = 0;
public void SetX(int a) { x = a; }
public void SetY(int a) { y = a; }
public void Print() {
9159.com,Console.WriteLine("x = {0} y = {1}", x, y);
}
static void Main(string[] args) {
StaticTest st = new StaticTest();
StaticTest st1 = new StaticTest();
st.SetX(10);      //将10赋给x;
st.SetY(10);      //将10赋给y;
st.Print(); //显示:x=10 y=10
st1.SetX(20);      //将20赋给x
st1.SetY(20);     //将20赋给x
st1.Print();   //显示:x=20 y=20
st.Print(); //由于x是静态变量,所以在此调用第一次初始化实例st时,静态变量已经变为20, 输出:x=20 y=10
st.SetX(30);   
    st.SetY(30); 
        st.Print();  
     //由于x是静态变量,所以在此调用初始化实例st时,静态变量已经变为30, 输出:x=30 y=30
st1.Print();
//由于x是静态变量,所以在此调用st1实例时,静态变量已经变为30, 输出:x=30 y=20
}
}
静态类:
声明为static,它仅包含静态成员,不能用new静态类的实例。使用静态类来包含不与特定对象关联的方法。
功能:仅包含静态成员,不能被实例化,是密封的,不能包含实例构造函数,可包含静态构造函数以分配初始值或设置某个静态变量。
优点:编译器能够执行检查以确保不致偶然地添加势力成员。编译器将保证不会创建此类的实例。
静态类是不能实例化的,我们直接使用它的属性与方法,静态类最大的特点就是共享。
探究
public static class StaticTestClass{
public static int n = 0;
public static void Add() {
n++;
}
}
网页 P1.aspx 调用 StaticTestClass.Add(),并在页面上输出 n。
网页 P2.aspx 调用 StaticTestClass.Add(),并在页面上输出 n。

访问者 V1 从客户端 C1 访问 P1.aspx,此时输出为 1。
访问者 V2 从客户端 C2 访问 P2.aspx,此时输出为 2。
访问者 V1 关闭浏览器,重新打开访问 P1.aspx,此时输出为 3。
静态方法:
是一种特殊的成员方法,不属于类的某一个具体的实例。非静态方法可以访问类中的任何成员,而静态只能访问类中的静态成员。

静态构造函数:
class SimpleClass{
// Static constructor
static SimpleClass() {

}}
一个类只能有一个静态构造函数,该构造函数不能有访问修饰符,不能带任何参数,不能直接调用,只能在:

1 创建包含静态构造函数的类实例时

2 访问包含静态构造函数的静态成员时

会先调用静态构造函数,无论创建了多少个类实例,其静态构造函数都只调用了一次。

用于对静态字段、只读字段等的初始化。              
添加static关键字,不能添加访问修饰符,因为静态构造函数都是私有的。      
类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数
静态构造函数是不可继承的,而且不能被直接调用。            
如果类中包含用来开始执行的 Main 方法,则该类的静态构造函数将在调用 Main 方法之前执行。任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项。  
如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数。

C#静态方法及属性在程序启动的时候,就全部装入内存的,而不管这些方法、属性以后有没有用到。即使是没有人再访问程序,这部分内存仍然不会释放还有就是,所有访问者看到的静态属性的数据几乎都是一样的,比如A用户设置了UserName这个属性,B用户访问的时候,得到的UserName仍然是A用户设置的那个。这种特性,如果用在固定数据中,那不会有太大问题,比如连接字符串之类的

C#静态方法/数据成员是属于类的,不是属于某一个对象的,因而调用它不需要实例化;静态方法和静态数据成员相当于共享变量。为该类的所有对象所共有,因而在需要共享数据时,定义这种类型时很好的选择。 一但定义一个类后(不一定要实例化对象)该类的所有静态成员就载入内存(并不是程序启动,就装入内存,没有定义该类时它不会载入内存) 静态成员的作用域与它所属的类的作用域相同

本文由9159.com发布于编程,转载请注明出处:之值类型和引用类型,在类中定义的字段为什么

关键词:

上一篇:没有了
下一篇:使用Linq查找重复