c#面试1(选择题)

1、下列有关基本类的大小不正确的是

A、int类型是4个字节

B、bool类型是1个字节

C、long类型是8个字节

Dchar类型是一个字节(2)


2、关于定义数组定义不正确的是

A、int[] numbers={1,2,3,4,5,6};

B、int[] numbers=new int[6];

C、int[][] numbers=new int[2][3];

D、var a=new[]{1,2,3,4,5,6};  var代表的是可变类型,但是后面必须指出具体类型。


3、有关数组说法不正确的是

A、数组的内存是分配在栈中  

B、数组的索引从零开始的

C、数组是一种数据结构,它包含若干相同的类型的变量

D、数组可以是一维、多维、交错的

4、有关结构体说法不正确的是

A、在结构体声明中,除非字段被声明为const或static,否则无法初始化

B、结构体不能声明默认的构造函数(没有参数的构造函数)或析构函数

由于结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数析构函数。实际上,编译器通过为所有字段赋予默认值来实现默认构造函数。
结构是值类型。那么如果从结构创建一个对象并将该对象赋给某个变量,则该变量包含结构的全部值。复制包含结构的变量时,将复制所有数据,对新副本所做的任何修改都不会改变旧副本的数据。由于结构不使用引用,因此结构没有标识;无法区分具有相同数据的两个值类型实例。

C、结构体不能从类或其他结构体继承

所有结构体都继承ValueType父类,但它们本身不能被其它类继承。
C#中的父类与子类的继承关系与C和C++中的类似,这里先阐述最重要的一点:假如子类继承了父类,那么子类可以强制转换为父类,并且保证编译和运行都不出错;但是父类强制转换成子类的时候,编译可以通过运行通不过。
实际上:将子类强制转换为父类之后,在用这个父类强制转换为另外一个子类的时候编译和运行也都能通过;只是如果将父类直接转换为子类的时候运行会出错。这就好比:假设父类是一个装了5个“苹果”的“小型篮子”,而子类则是一个装了5个“苹果”和5个”西瓜“的大型篮子;将子类强制转换为父类<=>把父类的”小型篮子“换成”大型篮子“,但还是只装5个”苹果“(将父类的引用指向子类,但父类只能调用父子自身的变量和方法),之后再用这个父类强制转换为另外一个子类<=>向”大型篮子“里面装入5个”西瓜“送给子类的引用;而将父类直接转换为子类<=>用父类的”小型篮子“装”5个苹果和5个西瓜“送给子类的引用(当然是装不下)
另外一个值得非常注意的地方是:无论是子类强制转换赋给父类,还是父类(由子类强转得到)强制转换为子类;类对象是根据声明的类型(子类或父类)去调用其变量和函数的,与赋值无关。

可以看出:类的实例对象在调用其变量和方法时,确实是以 声明 成为的类为依据的。

D、结构体是引用类型的  ( 结构体是值类型的 类是引用类型的)



结构体中无法对静态或者常量字段3进行初始化

 

结构体中的静态变量都是通过结构体名字获得。

 

 

结构体不能有显示不带参数的构造函数

 

如果结构体中有非3静态字段或非常量,如果有显示带参数的构造函数话,必须在构造函数中对其赋值。

 

析构函数:如果类中写了对应的析构函数的话,当这个类的实例在程序的引用为空,则会自动调用这个析构函数

GC如果类中没有写析构函数的话,则当类的实例在程序中的引用为空,GC会回收这段内存。

构造函数可以重载,析构函数不能重载。

结构体不能有析构函数,只有类类型才有析构函数。

 

 

 

  当这个类在程序中的引用结束



5、有关结构体和类的说法不正确的是

A、结构是值类型的,而类是引用类型的

B、结构体不可以声明构造函数(可以申明默认的构造函数)

C、结构体直接继承System.ValueType类型

D、结构体可以继承接口

  public struct MyS : IStruct
        {
            public void SayHello()
            {
                Console.WriteLine("Hello");
            }
        }
        public interface IStruct
        {
            void SayHello();
        }

结构体是值类型当然可以继承接口,接口相当于方法模型,结构里面可以写方法,当可以实现接口

       结构体派生自ValueType ValueType派生自Object,可访问Object的方法。

       结构体是一种缩小版的类。

       结构体不能继承。

结构体总是有一个无参数的默认构造函数,不允许替换。

结构体可指定字段如何在内存中布局。

结构体在很多方面和类相同。

但有些与类不同,结构的实例化可以不适用new运算符,类不行。

结构体可以声明构造函数,但它们必须带参数,不能重写默认的构造函数。

更重要的是他不能继承。


可以说结构体和类一样,只不过结构体中定义的变量或者方法的默认访问属性是public的,而类是private的


6、有关类和结构体的区别说法不正确的是

A、结构体是值类型的,而类是引用类型的

B、类的实例化需要new,而结构体可以不用

C、结构体内存一定分配在栈中,而类的内存分配在堆中

使用malloc函数新建一个结构体是在堆上分配的,。

D、结构可用作可为null的类型,因而可向其赋值null

7、关于静态类说法不正确的是

A、声明静态类,该类不能使用new关键字创建实例

B、静态类仅包含静态成员(对)

C、静态类不能包含常量成员

D、静态类是密封的(对)

  • 静态类可以有静态构造函数,静态构造函数不可继承。
静态类的主要特性:
1:仅包含静态成员。
2:无法实例化。
3:是密封的,不能被继承。
4:不能
包含实例构造函数。


静态类主要是共享,静态类内部成员必须是静态的。
静态一般在程序加载的时候被构造。

我个人用静态类最多的地方的是程序配置部分,因为他的共享特性,在多个窗体中都需要调用,更主要的就是他在程序启动的时候就被初始化了。

静态类可以有构造函数,但是只被调用一次。

就上面说的程序配置数据部分,如果使用非静态类,那么你需要在任何有可能访问到他的代码前手动初始化他,并且还要将他赋给一个静态变量后才能使用。
费事不费事另说,假若你需要在他构造前某个位置来调用它,那还需要修改你构造他的代码的位置。

非静态类使用完成后系统会自动销毁释放,所以非静态类相对来说比较安全,而静态类是在程序结束后销毁的,在销毁前一直驻留在内存中,因此出现错误的可能性会大些。

建议不要过多的使用静态类,适时使用。

静态类

非静态成员(字段、属性、和方法)或者非常量是属于类的实例的。

静态类是密封的。也不能被继承

 

静态构造函数的调用不是由用户自己调用的,而是系统系统调用的。

静态类不能调用析构函数。


8、有关静态成员说法不正确的是

A、可以使用类的实例,访问本身类的静态的成员

B、静态方法可以被重载,但不能被重写

C、静态成员在第一次被访问之前并且在任何静态构造函数之前初始化

D、可以在类中声明静态成员


无法使用类的实例去访问静态成员,静态成员不是不属于类的对象的

静态方法不能标记为override virtual abstract 


9、有关委托的说法不正确的是

A、一旦为委托分配了方法,委托与该方法具有完全相同的行为

B、委托是一种引用方法的类型

C、委托可以链接在一起,方法不必与委托签名完全匹配

D、委托就是事件一种表示形式


 

委托是引用类型


10、delegate void Del(int x);

      void DoWork(int k);

下列关于委托订阅不正确的是

A、Del d=DoWork;

B、Del d=new Del(DoWork);

C、Del d+=DoWork

D、Del d=delegate(int x){DoWork(x);};


11、有关静态构造函数说法不正确的是

A、静态构造函数既没有访问修饰符,也没有参数

B、在创建第一个实例前或引用任何静态成员之前,将自动调用静态构造函数来初始化。

C、在程序中,用户可以控制何时执行静态构造函数

D、无法直接调用静态构造函数


静态构造函数必须没有参数


12、有关absract关键字说法不正确的是

A、absract用于创建仅用于继承用途的类和类的成员

B、absract用于方法,则该方法隐含是虚函数

C、absract用于类,则此类无法被实例化

D、absract用于方法,则该方法有方法体

虚方法virtual的意思是子类可以重写,抽象方法abstract是子类必须重写。

抽象方法必须能被继承


13、有关继承需要用的关键字说法不正确的是

A、virtual用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。

Bvirtual可以和staticabstractprivateoverride修饰符一起使用

C、override关键字提供从基类继承的成员的新的实现,重写的基类方法必须是virtual、abstract、或override关键字修饰的。

D、Sealed用于修饰类时,将会阻止其他类从该类派生

14、有关索引器说法不正确的是

A、索引器允许类或结构体的实例就像数组一样进行索引

B、索引器类似于属性,不同之处在于他们的访问器采用参数

C、索引器不可被重载

 

D、索引器不必根据整数值进行索引,由你决定如何定义特定的查找机制

Public int this[int index]

{

       set{}

get{}

}

 

索引器(Indexer)

C#引入的一个新型的类成员,它使得类中的对象可以像数组那样方便、直观的被引用。索引器非常类似于属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用。定义了索引器的类可以让您像访问数组一样的使用 [ ] 运算符访问类的成员。(当然高级的应用还有很多,比如说可以把数组通过索引器映射出去等等)

      本文只是简单演示一下索引器的概念和基本的使用方法:

请看代码,下面是类的定义,中间包含了一个索引器定义

[csharp] view plain copy

 

1.  类的定义  

2.     public class Person  

3.      {  

4.         //定义两个字段信息  

5.          private string name;  

6.         private string password;  

7.    

8.         //定义一个 Name 属性来操作 name 字段  

9.          public string Name  

10.        {  

11.             set { name = value; }  

12.            get { return name; }  

13.         }  

14.  

15.         //定义一个 Password 属性来操作 password 字段  

16.        public string Password  

17.         {  

18.            set { password = value; }  

19.             get { return password; }  

20.        }  

22.        //定义索引器,name 字段的索引值为 0 password 字段的索引值为 1  

23.         public string this[int index]  

24.        {  

25.             get  

26.            {  

27.                 if (index == 0) return name;  

28.                else if (index == 1) return password;  

29.                 else return null;  

30.            }  

31.             set  

32.            {  

33.                 if (index == 0) name = value;  

34.                else if (index == 1) password = value;  

35.             }  

36.        }  

37.     }  


下面是使用索引器的方法:

[csharp] view plain copy

 

1.  索引器使用  

2.     protected void Page_Load(object sender, EventArgs e)  

3.      {  

4.         //声明并实例化这个类  

5.          Person p = new Person();  

6.   

7.          //使用索引器的方式来给类的两个属性赋值  

8.         p[0] = "jarod";  

9.          p[1] = "123456,./";  

10.  

11.         //使用类属性取得两个字段信息  

12.        Label1.Text = p.Name + " / " + p.Password;  

13.     }  


 非常简单,在上面的类中我们把类的 name字段映射的索引值为 0,而password字段映射的索引值为 1。有了这个映射就可以使用以下方式为类的 name password赋值了。

 

 

 p[0] = "jarod";    //设置 name 字段值
 p[1] = "123456,./";  //设置 password 字段值

 

赋值后,就可以使用属性方法访问到刚刚给两个字段赋的值了。


15、在C#中,下列常量定义正确的是(    )

A、Const double PI 3.1415926;

B、Const double e=2.7

C、define double PI 3.1415926

D、define double e=2.7


16、以下c#代码:

usingSystem.Threading;

class App{

            public static void Main(){

              Timertimer = new Timer(new TimerCallback(CheckStatus),null,0,2000);

              Console.Read();

}

static void CheckSatus(Object state){

       Console.WriteLine("正在进行检查...")

     }

}

在使用代码创建定时器对象的时候,同时指定了定时器的事件,运行时将每隔两秒打印一行“正在运行检查...”,因此,TimerCallback是一个(   )

A.委托

B.结构

C.函数

D.类名


21、以下的C#代码段:

         public struct Person{

             string Name;

             int Age;

         }

         public static void Main(){

             Hasbtable A;

             Person B;

            //其他处理代码

         }

         以下说法正确的是(     )。(选择一项)

A.A为引用类型的变量,B为值类型的变量

B.A为值类型的变量,B为引用类型的变量

C.A和B都是值类型的变量

D.A和 B都是引用类型的变量



24、在C#语言中,下列关于属性的描述正确的是(     ).(选择一项)

A.属性系是以public关键字修饰的字段,以public关键字修饰的字段也可称为属性

B.属性是访问字段值的一种灵活机制,属性更好地实现了数据的封装和隐藏

C.要定义只读属性只需在属性名前加上readonly关键字

D.在C#的类中不能自定义属性

 

28、阅读以下的C#代码:

    class A{

         public A( ) {

               Console.WriteLine("A");

          }

      }

      class B:A{

          public B(){

             Console.WriteLine("B");

          }

      }

    class Program{

       public static void Main(){

           B b = new B();

           Console.ReadLine();

       }

    }

上述代码运行后,将在控制台窗口输出(    )。

A. A

B. B

C. A B

D.B A


29、在.NET中,以下关于命名空间的描述,正确的是(      )。

A.命名空间不可以进行嵌套

B.任一个.cs文件中,只能存在一个命名空间

C.便用private修饰的命名空间,其内部的类也不允许访问

D.命名空间使得代码更加有条理、结构更清晰

30、NET中,程序中的错误可以划分为以下三类,除了(      )。 

A.逻辑错误

B.运行时错误

C.语法错误

D.自定义错误

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值