C# 几道程序题
时间:2010-10-28 来源:小鱼儿-fly
ref与out的区别: ref必须初始化,out必须在函数内部初始化。ref ,out必须显示使用。out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。
ex1:
class Class1
{
private string str="Class1.private";
private int i = 0;
static void StringConvert(string str)
{
str = "converted";
Console.WriteLine("This is the StringConvert()!");
}
static void StringConvert(Class1 c)
{
c.str = "string being converted";
Console.WriteLine("This is the StringConvert(Class1)!");
}
static void Add(int i)
{
i++;
Console.WriteLine("This is the Add()!");
}
static void AddWithRef(ref int i)
{
i++;
Console.WriteLine("This is the AddWithRef()!");
}
static void Main()
{
int i1 = 10;
int i2 = 20;
string str = "str111";
Class1 c = new Class1();
Add(i1);
AddWithRef(ref i2);
StringConvert(str);
StringConvert(c);
Console.WriteLine(i1);//没有使用ref,所以不会影响原值。其改变只在函数内部有效
Console.WriteLine(i2);// 使用了ref 所以会影响的原值,当调用了StringConvert函数是i2加1.
Console.WriteLine(c.i);//i是class1声明的私有变量值为1,在主函数中没有对i进行任何操作,所以其值不变
Console.WriteLine(str); //str 是引用类型,则若不适用ref,变量只在方法内部有效,也就是不会影响str的初始值。
Console.WriteLine(c.str);//当运行StringConvert(c)时,c.str被赋值。
Console.ReadLine();
}
}
ex2:
class PassingRefByRef
{
static void Change(ref int[] pArray)
{
// Both of the following changes will affect the original variables:
pArray[0] = 888;
pArray = new int[5] {-3, -1, -2, -3, -4};
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}
static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);
Change(ref arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
}
}
2.本题主要考察静态构造函数问题。需要注意以下几点:
- 用于对静态字段、只读字段等的初始化;
- 添加static关键字,不能添加访问修饰符,因为静态构造函数都是私有的
- 类的静态构造函数在给定应用程序域中至多执行一次,只有创建类的实例或者引用类的任何静态成员才激发,不能带又参数
- 静态构造函数是不可继承的,而且不能被直接调用;
- 如果类中包含用来开始执行的 Main 方法,则该类的静态构造函数将在调用 Main 方法之前执行.任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项;
- 如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数;
- 一个类可以同时拥有实例构造函数和静态构造函数,这是惟一可以具有相同参数列表的同名方法共存的情况
class Class1
{
public static int Count = 0;
//静态构造函数当类被实例化时至多被调用一次
static Class1()
{
Count++;
Console.WriteLine("This is the static{0}", Count);
}
//构造函数 每当类被实例化时都被调用
public Class1()
{
Count++;
Console.WriteLine("This is the public{0}",Count);
}
static void Main()
{
Class1 c = new Class1();
Console.WriteLine(Class1.Count);
Class1 c1 = new Class1();
Class1 c2 = new Class1();
Console.WriteLine(Class1.Count);
Console.ReadLine();
}
}
3.本题主要考察继承问题.
public abstract class A
{
public A()
{
Console.WriteLine('A');
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
}
public class B : A
{
/*因为b继承A,父类能声明一个子类实例,但子类不能声明父类。 但当实例化子类时,
不但调用子类构造函数,父类构造函数也会调用*/
public B()
{
Console.WriteLine("B");
}
public new void Fun()
{
Console.WriteLine("B.Fun()");
}
public static void Main()
{
A a = new B();
a.Fun();
B b = new B();
b.Fun();
Console.ReadLine();
}
}
public class A
{
public virtual void Fun1(int i)
{
Console.WriteLine(i);
}
public void Fun2(A a)
{
a.Fun1(1); //fun2传入一个类A的形参,并调用A中Fun1方法---输出:1
Fun1(5); //因为fun2 fun1在同一类中 可直接调用 --输出:5
}
}
public class B : A
{
public override void Fun1(int i)
{
base.Fun1(i+1); //重写fun1方法,调用父类fun1方法 但参数为i+1
}
public static void Main()
{
B b = new B(); //实例化B类
A a = new A(); //实例化A类
a.Fun2(b); //传入b类型参数 则调用b.fun1(1)a.fun(5) 输出:2 5
b.Fun2(a);// a.fun1 b.fun(5) 1 6
Console.ReadLine();
}
}