C# 基础·常见面试

1、WinForm遍历控件

foreach (System.Windows.Forms.Control control in this.Controls) 
{ 
if (control is System.Windows.Forms.TextBox) 
{ 
System.Windows.Forms.TextBox tb = (System.Windows.Forms.TextBox)control ;  
tb.Text = String.Empty ; 
} 
}
View Code

 2、C# 打印倒置三角

static void Main(string[] args)
        {
            int intNumber;

            Console.Write("请输入显示的行数:");
            string number = Console.ReadLine();

            bool IsNum = int.TryParse(number, out intNumber);

            if (!IsNum)
            {
                Console.Write("请不要输入非法数字!");
            }
            else if (intNumber < 3 || intNumber > 21)
            {
                Console.Write("输入的数据最小为3,最大为21!");
            }
            else
            {
                for (int i = intNumber; i > 0; i--)
                {
                    //循环空格
                    for (int j = 0; j < intNumber - i; j++)
                    {
                        Console.Write(" ");
                    }

                    //循环图形
                    for (int k = 2 * i - 1; k > 0; k--)
                    {
                        Console.Write("*");
                    }

                    Console.Write("
");
                }
            }
            Console.ReadKey();
        }
View Code

 3、Random 产生随机数组

做法1:

            List<int> list = new List<int>();

            Random rand = new Random();

            while (list.Count < 100)

            {

                int number = rand.Next(1, 101);//>=1,<101

                if (!list.Contains(number))//如果list中已经含有这个数,则不插入

                {

                    list.Add(number);

                }

            }

 

            foreach (int i in list)

            {

                Console.WriteLine(i);

            }

 

做法2:

先把1-100这100个数按顺序放入数组arr,再重复100次下面的操作,生成两个介于 >=0,<100 之间的随机数m、n,颠倒arr[m]和arr[n]的数。

 

            int[] arr = new int[100];

            //把100个数顺序放入

            for (int i = 0; i < 100; i++)

            {

                arr[i] = i + 1;

            }

 

            Random rand = new Random();

            for (int i = 0; i < 100; i++)

            {

                //随机生成两个位置

                int m = rand.Next(0, 100);

                int n = rand.Next(0, 100);

 

                //颠倒两个位置

                int temp = arr[m];

                arr[m] = arr[n];

                arr[n] = temp;

            }
View Code

4、ref与out的区别

ref和out的使用与区别

 
out的使用

————————————————————————————————————————————————— 

   class Program
    {
        static void Main(string[] args)
        {

     string tmp;    //先声明,但不初始化

     User _user=new User();      

     _user.Name(out tmp);        //调用Name方法

              Console.WriteLine("{0}",tmp); //这时tmp的值为“在这里面赋值了”

              Console.ReadKey(true);

   }

     }

  class User

      {

    public void Name(out string tmps)

           {

       tmps="在这里面赋值了";

           }

      }

       结果:

              在这里面赋值了

—————————————————————————————————————————————————

 ref的使用

—————————————————————————————————————————————————

 

   class Program
    {
        static void Main(string[] args)
        {

     string tmp="传值之前";    //声明并初始化        这时如果输出tmp值为"传值之前"

          User _user=new User();

              _user.Name(ref tmp);

              Console.WriteLine("{0}",tmp);

              Console.ReadKey(true);

        }

    }

    class User

    {

         public void Name(ref string tmps)

         {

              tmps="传值之后";

         }

    }

    结果:

          传值之后

—————————————————————————————————————————————————

区别:

ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:

1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。

2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。

3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。

out

方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。

若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。

不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。

属性不是变量,不能作为 out 参数传递。

 

ref是    有进有出,而out是       只出不进。
View Code

5、说说对封装、继承、多态的理解

封装:
 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。 

 封装的意义:
  封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

1. 保护数据成员,不让类以外的程序直接访问或修改,只能通过提供的公共的接口访问==>数据封装。

2. 方法的细节对用户是隐藏的,只要接口不变,内容的修改不会影响到外部的调用者==>方法封装。 

3. 当对象含有完整的属性和与之对应的方法时称为封装。

4. 从对象外面不能直接访问对象的属性,只能通过和该属性对应的方法访问。

5. 对象的方法可以接收对象外面的消息。

即类的方法和成员变量的访问控制符,一个类作为整体对象不可见,并不代表他的所有域和方法也对程序其他部分不可见,需要有他们的访问修饰符判断。

继承:
继承主要实现重用代码,节省开发时间。

、C#中的继承符合下列规则:

继承是可传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。Object类作为所有类的基类。
派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。
构造函数和析构函数不能被继承。除此之外的其它成员,不论对它们定义了怎样的访问方式,都能被继承。基类中成员的访问方式只能决定派生类能否访问它们。
派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但这并不因为这派生类删除了这些成员,只是不能再访问这些成员。
类可以定义虚文法、虚属性以及虚索引指示器,它的派生类能够重载这些成员,从而实现类可以展示出多态性。
、new关键字

   如果父类中声明了一个没有friend修饰的protected或public方法,子类中也声明了同名的方法。则用new可以隐藏父类中的方法。(不建议使用)

、base关键字

   base 关键字用于从派生类中访问基类的成员:

调用基类上已被其他方法重写的方法。
指定创建派生类实例时应调用的基类构造函数。
多态:
1、“一个接口,多种方法”
同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
 
多态的三个条件:



a.    继承的存在(继承是多态的基础,没有继承就没有多态).

b.    子类重写父类的方法(多态下调用子类重写的方法).

c.    父类引用变量指向子类对象(子类到父类的类型转换).
重载(overload)和重写(override)是实现多态的两种主要方式。
、实现多态:

接口多态性。
继承多态性。
通过抽象类实现的多态性。
View Code

 6、拓展方法

//必须是静态类才可以添加扩展方法
Static class Program
       {
        static void Main(string[] args)
        {
            string str = "quzijing";
//注意调用扩展方法,必须用对象来调用 
            string Newstr = str.Add();
            Console.WriteLine(Newstr);
            Console.ReadKey();
        }
//声明扩展方法
        //扩展方法必须是静态的,Add有三个参数
        //this 必须有,string表示我要扩展的类型,stringName表示对象名
        //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,//再增加一个变量即可

        public static  string  Add(this string stringName)
        {
            return stringName+"a";
        }
}
View Code
原文地址:https://www.cnblogs.com/eric-gms/p/5599726.html