1索引器
索引器的目的就是为了方便而已,可以再该类型的对象后面直接加一对[]就能访问该类型中的成员内容了。
class Program
{
static void Main(string[] args)
{
////索引器的目的就是为了方便而已,可以在该类型的对象后面直接加一对中括号[]就能访问该类型中的成员内容了
Person p = new Person();
p[0] = 19;
Console.WriteLine(p[0]);
p[1] = "张三";
Console.WriteLine(p[1]);
p[2] = "zhangsan@yahoo.com";
Console.WriteLine(p[2]);
Console.WriteLine(p["age"]);
Console.ReadKey();
MyClass mc = new MyClass();
//mc._cars[0];
// mc[0]
for (int i = 0; i < mc.Length; i++)
{
Console.WriteLine(mc[i]);
}
//Console.ReadKey();
ItcastClass ic = new ItcastClass();
ic[0] = "aaaa";
for (int i = 0; i < ic.NameLength; i++)
{
Console.WriteLine(ic[i]);
}
Console.ReadKey();
}
}
public class MyClass
{
private string[] _cars = new string[] { "奔驰", "宝马", "法拉利", "福特", "布加迪威龙" };
public int Length
{
get
{
return _cars.Length;
}
}
//索引器最终编译的的时候会生成一个名字叫Item的属性
public string this[int index]
{
get
{
return _cars[index];
}
set
{
_cars[index] = value;
}
}
//public string Item
//{
// get;
// set;
//}
}
public class Person
{
//增加一个索引器, 索引器的语法格式与类的属性的语法格式很像、
private int _age;
public object this[int index]
{
get
{
switch (index)
{
case 0:
return _age;
case 1:
return _name;
default:
return _email;
}
}
set
{
switch (index)
{
case 0:
this._age = Convert.ToInt32(value);
break;
case 1:
this._name = (value == null) ? null : value.ToString();
break;
default:
this._email = (value == null) ? null : value.ToString();
break;
}
}
}
public object this[string key]
{
get
{
switch (key)
{
case "age":
return _age;
case "name":
return _name;
default:
return _email;
}
}
set
{
switch (key)
{
case "age":
this._age = Convert.ToInt32(value);
break;
case "name":
this._name = value == null ? null : value.ToString();
break;
default:
this._email = value == null ? null : value.ToString();
break;
}
}
}
private string _name;
private string _email;
}
2,访问修饰符
作用:指明程序的其他部分如何访问该成员。共5种
private 当前类中可以访问,类中成员的默认访问修饰符
protected 当前类和子类可以访问(在继承中用)
internal 当前程序集内部可以访问,类如果不加访问修饰符,则默认为internal
protected internal 当前程序集或子类中(不同程序集也可以访问)
public 任何地方
访问级别约束
1)子类的访问级别不能比父类高(会暴漏父类的成员)
2)类中属性或字段的访问级别不能比所对应的类型访问级别高
3)方法的访问级别不能比方法的参数和返回值的访问级别高
3,静态类和静态成员
静态成员是与“类”相关,而非“实例相关”。
普通类中的静态成员static:只能通过类名访问,静态方法中只能访问静态成员,或通过对象访问实例成员,多个对象共享同一个静态成员
静态类:一般都用作工具类,里面都是一些工具函数,静态类中只包含静态成员,静态构造函数不能有参数,不能有访问修饰符(默认private)静态构造函数在第一次使用该静态类的时候只执行一次。
静态成员属于类所有,非静态成员属于类的实例所有
C#静态方法属于所有类,类实例化前即可使用。在实例方法中可以直接调用静态方法,在静态方法中不能直接调用实例方法。
静态方法和静态变量创建后始终使用同一内存块(静态存储区),而实例的方法会创建多个内存。
静态类和静态成员在程序中的任何一个地方都可以访问,不会因为超出了方法的作用域而不能访问,所以静态类和静态成员只有在程序退出的时候才会释放资源
静态类不能被实例化,就不会由对象,而this表示的是当前对象,所以静态类中不能使用this
静态和非静态的区别:1)、在非静态类中,既可以有实例成员,也可以有静态成员。2)、在调用实例成员的时候,需要使用对象名.实例成员;
在调用静态成员的时候,需要使用类名.静态成员名;
总结:静态成员必须使用类名去调用,而实例成员使用对象名调用。 静态函数中,只能访问静态成员,不允许访问实例成员。 实例函数中,既可以使用静态成员,也可以使用实例成员。静态类中只允许有静态成员,不允许出现实例成员。
什么时候用静态类:
1>在整个应用程序中要共享某些数据的时候可以使用静态类。
2>静态类不能创建对象,使用的时候直接通过类名来操作成员,(使用方便),所以说对于那些类中包含有大量的方法,并且类不需要创建对象的时候,可以使用静态类。
静态 | 非静态 |
static关键字 | 不需要static关键字 |
使用类名调用 | 使用实例对象调用 |
在静态方法中可以访问静态成员 | 在实例方法中,可以直接访问静态成员 |
在静态方法中不可以直接访问实例成员 | 在实例方法中可以直接访问实例成员 |
调用前初始化 | 实例化对象时初始化 |
4,值类型和引用类型
值类型:int char double floatlongshortbyteboolenumstructdecimal
值类型都是隐式继承自ValueType,值类型不能继承,只能实现接口,存放在栈中。
引用类型:string数组类接口委托
引用类型都派生自System.Object,引用类型可以继承。 存放在堆中。
ref把值类型改为引用类型
区别:
1、值类型和引用类型在内存上存储的地方不一样。
2、在传递值类型和传递引用类型的时候,传递的方式不一样。
结构中不能有显示无参构造函数(隐式),结构中不能给字段赋初始值。
值类型和引用类型作为参数 引用传递
class Program
{
static void Main(string[] args)
{
#region 值类型与引用类型介绍
//// 值类型, 栈
////int short byte char bool double float struct enum decimal
////引用类型 string 数组 类 接口 委托
////堆
//string s = "a";
//s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
////值类型
//int n = 100;
//int m = n;
//m = m + 1;
//Console.WriteLine(n);
//Console.ReadLine();
////引用类型
//Person p = new Person();
//p.Age = 100;
//Person p1 = p;
//p1.Age = 120;
//Console.WriteLine(p.Age);
//Console.ReadKey();
#endregion
int n = 10;
M1(ref n);
Console.WriteLine(n);//11
//Console.ReadKey();
Person p = new Person();
p.Age = 100;
M2(ref p);
Console.WriteLine(p.Age);//101
Person p1 = new Person();
p1.Age = 100;
M3(ref p1);
Console.WriteLine(p1.Age);//200
Person p2 = new Person();
p2.Age = 100;
M4(ref p2);
Console.WriteLine(p2.Age);//1
string name = "科比";
M5(ref name);
Console.WriteLine(name);//乔丹
int[] arrInt = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
M6(ref arrInt);
//0000000
for (int i = 0; i < arrInt.Length; i++)
{
Console.WriteLine(arrInt[i]);
}
int[] arrInt1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
M7(ref arrInt);
//12345678
for (int i = 0; i < arrInt1.Length; i++)
{
Console.WriteLine(arrInt1[i]);
}
#region MyRegion
Console.ReadKey();
#endregion
}
// 值类型 与 引用类型 作为参数 【引用传递】
private static void M7(ref int[] arrInt)
{
for (int i = 0; i < arrInt.Length; i++)
{
arrInt[i] = 100;
}
}
private static void M6(ref int[] arrInt)
{
arrInt = new int[arrInt.Length];
for (int i = 0; i < arrInt.Length; i++)
{
arrInt[i] = arrInt[i] * 2;
}
}
private static void M5(ref string name2)
{
name2 = "乔丹";
}
private static void M4(ref Person p1)
{
p1 = new Person();
p1.Age++;
}
private static void M3(ref Person p1)
{
p1.Age = 1000;
p1 = new Person();
p1.Age = 200;
}
private static void M2(ref Person p1)
{
p1.Age++;
}
//值传递,传递的是栈中的内容,(对于值类型,栈中的内容就是对应的数据。对于引用类型栈中内容就是对象的地址)
//引用传递,传递的是栈本身的地址,多个变量名实际上指向的是同一个栈变量。
//引用传递必须使用ref关键字修饰。在方法调用的时候传递参数的时候也必须加ref 关键字
private static void M1(ref int m)
{
m++;
}
}
class Person
{
public int Age
{
get;
set;
}
}
</pre><span style="white-space:pre"></span><span style="background-color: rgb(255, 255, 0);">值类型 与引用类型 作为参数 值传递<</span>p></p><p></p><pre name="code" class="csharp">class Program
{
static void Main(string[] args)
{
#region 值类型与引用类型介绍
//// 值类型, 栈
////int short byte char bool double float struct enum decimal
////引用类型 string 数组 类 接口 委托
////堆
//string s = "a";
//s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
////值类型
//int n = 100;
//int m = n;
//m = m + 1;
//Console.WriteLine(n);
//Console.ReadLine();
////引用类型
//Person p = new Person();
//p.Age = 100;
//Person p1 = p;
//p1.Age = 120;
//Console.WriteLine(p.Age);
//Console.ReadKey();
#endregion
int n = 10;
M1(n);
Console.WriteLine(n);//10
Console.ReadKey();
Person p = new Person();
p.Age = 100;
M2(p);
Console.WriteLine(p.Age);//101
Person p1 = new Person();
p1.Age = 100;
M3(p1);
Console.WriteLine(p1.Age);//1000
Person p2 = new Person();
p2.Age = 100;
M4(p2);
Console.WriteLine(p2.Age);//100
string name = "科比";
M5(name);
Console.WriteLine(name);//科比
int[] arrInt = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
M6(arrInt);
//12345678
for (int i = 0; i < arrInt.Length; i++)
{
Console.WriteLine(arrInt[i]);
}
int[] arrInt1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
M7(arrInt1);
//100,100,100,100,100,100,100,100
for (int i = 0; i < arrInt1.Length; i++)
{
Console.WriteLine(arrInt1[i]);
}
Console.ReadKey();
}
#region 值类型 与 引用类型 作为参数 【值传递】
//值传递:
private static void M7(int[] arrInt)
{
for (int i = 0; i < arrInt.Length; i++)
{
arrInt[i] = 100;
}
}
private static void M6(int[] arrInt)
{
arrInt = new int[arrInt.Length];
for (int i = 0; i < arrInt.Length; i++)
{
arrInt[i] = arrInt[i] * 2;
}
}
private static void M5(string name2)
{
name2 = "乔丹";
}
private static void M4(Person p1)
{
p1 = new Person();
p1.Age++;
}
private static void M3(Person p1)
{
p1.Age = 1000;
p1 = new Person();
p1.Age = 200;
}
private static void M2(Person p1)
{
p1.Age++;
}
private static void M1(int m)
{
m++;
}
}
值类型和引用类型的区别