zoukankan      html  css  js  c++  java
  • C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱

    一.前言

    -孤独的路上有梦想作伴,乘风破浪-

    二.页面值传递

    (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转、计算等操作)。为了实现多种方式的数据传递,C#提供一下几种方式:

    1.Query.String方式

    2.Server.Transfer方式

    3.Cookie方式

    4.Session方式

    5.Application方式

    (2)实现方式

    新建TestTransfer项目,添加TransferOne.aspx页面和TransferTwo.aspx页面。在TransferOne.aspx中,添加两个文本框和一个按钮,用来实现跳转。在btnLogin_Click中添加实现的逻辑代码:

    在TransferTwo.aspx中添加:

    在Page_Load中添加逻辑实现代码,

    以上就是c#页面之间传值的几种方式,其中Query.String方式在URl地址栏中会显示传递的的参数值信息。

    注意:Session与Cookie的区别

    由于Http协议是基于Tcp/Ip的,当用户从客户端发送请求到服务端,服务端响应请求,并返回数据给客户端,这个过程是无状态的,为了保存客户端的某些状态,因此用到了Session和Cookie机制。

    (1)session存储在服务端,cookie是存储在客户端,并且存储的大小有限制。

    (2)session实现的本质是依靠cookie来做的,一般把具有敏感信息的内容用session存储在服务端,例如密码等。首先在服务端生成session以后,返回SessionID给客户端,客户端Cookie保存SessionID的值,

    下次请求的时候带着SessionID去获取对应的Session的值。

    (3)Cookie存在有效期,可以设置cookie的有效期。

    声明Cookie的方式:

    var cookie = Request.Cookies["user"] ?? new HttpCookie("user");

    cookie.Values.Set("username", this.TextBox1.Text);

    cookie.Values.Set("password", this.TextBox2.Text);

    Response.SetCookie(cookie);

    Response.Cookies.Add(cookie);

    声明Session方式:

    Session["username"] = this.TextBox1.Text;

    Session["password"] = this.TextBox2.Text;

    三、重载与重写、隐藏

    (1)定义:

    重载:同一个作用域内发生(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同。这样才能通过传递不同的参数来决定到底调用哪一个。返回类型可以相同也可以不同。

    重写:继承时发生,在子类中重新定义父类中的方法,子类中的方法和父类的方法是一样的。例如:基类方法声明为virtual(虚方法),派生类中使用override申明此方法的重写.

    隐藏:基类方法不做申明(默认为非虚方法),在派生类中使用new声明此方法的隐藏。子类覆盖基类的方法,其返回值类型必须相同。

    (2)实现Demo

    static void Main(string[] args)

    {

    var coderOne=new DoWork();

    coderOne.DoCoding("liupeng");

    coderOne.DoCoding("liupeng", 24);

    var coderTwo=new SubDoWork();

    coderTwo.Say();

    //隐藏基类的方法

    coderTwo.EnjoyLife();

    //通过实例化的对象,决定调用基类还是子类中的方法

    coderOne.EnjoyLife();

    Console.ReadKey();

    }

    public class DoWork

    {

    public virtual void Say()

    {

    Console.WriteLine("I am in Base Calss,Hello Everyone!");

    }

    public void EnjoyLife()

    {

    Console.WriteLine("I am a Coder, but I like my life, Coding is my life,also is my girl! Haha!");

    }

    public void DoCoding(string name)

    {

    Console.WriteLine(string.Format("My name is {0},I love coding!", name));

    }

    public void DoCoding(string name, int age)

    {

    Console.WriteLine(string.Format("My name is {0},age is {1},I always love coding!", name, age));

    }

    }

    public class SubDoWork : DoWork

    {

    public override void Say()

    {

    Console.WriteLine("I am in SubClass,Hello Everybody!");

    }

    new public void EnjoyLife()

    {

    Console.WriteLine("I am a  new bird ,i must work hard to achieve my dream!");

    }

    }

    四、类与结构体

    1.关于类和结构体的区别:

    (1)类中传递的内容是存储在托管堆中,而结构体中传递的内容是存储在栈中。

    (2)类中传递的对象修改的时候,将修改源对象;而结构体中的对象修改时,源对象不会改变,保持原来的状态。

    (3)类中的构造函数,可以是默认无参的构造函数,也可以是有参数的构造函数;但结构中的构造函数必须为有参数的构造函数,不能为默认的构造函数。

    2.实现Demo

    static void Main(string[] args)

    {

    Console.WriteLine("-----------初始化之前的字段的值--------------");

    var studentOne = new StuName("zhangyonghe", 26);

    var studentTwo = new StructStuName("liupeng", 25);

    studentOne.SayHello();

    studentTwo.SayHello();

    Console.WriteLine("--------------修改对象的传递时的值------------");

    var studentOneNew = studentOne;

    studentOne.Age = 30;

    studentOne.SayHello();

    var studentTwoNew = studentTwo;

    studentTwoNew.Age = 35;

    studentTwo.SayHello();

    Console.ReadKey();

    }

    public class StuName

    {

    public string Name { get; set; }

    public int Age { get; set; }

    public StuName(string name, int age)

    {

    this.Name = name;

    this.Age = age;

    }

    public void SayHello()

    {

    Console.WriteLine(string.Format("Class类结构的姓名为:{0},年龄为:{1}", Name, Age));

    }

    }

    public struct StructStuName

    {

    public string Name;

    public int Age;

    //结构体的构造函数必须滴啊有参数

    public StructStuName(string name, int age)

    {

    Name = name;

    Age = age;

    }

    public void SayHello()

    {

    Console.WriteLine(string.Format("Struct结构的姓名是:{0},年龄是:{1}", Name, Age));

    }

    }

    运行结果为:

    五.装箱与拆箱

    (1)定义:将值类型转化为引用类型为装箱;将引用类型转化为值类型称之为拆箱。

    (2)熟悉一段代码:

    public void Method1(){

    // Line 1

    int i=4;

    // Line 2

    int y=2;

    //Line 3

    class1 cls1 = new class1();

    }

    此时,程序是这样解析的:

    (1)先在栈上根据值类型的大小分配相应的内存空间,将值类型变量的Value存在栈空间上。

    (2)当执行到实例化一个对象cls1时,编译器在站上创建了一个指针,真实的对象存储在另一种叫“堆”的内存中。

    "堆"并不跟踪运行内存,它更像一堆随时可以访问的对象。堆用于动态分配内存。这里需要着重说明的是引用指针是分配在栈上。

    声明Class1 cls1时并不会给Class1的实例分配内存,而是分配一个栈变量cls1(并设置为null),然后把它指向“堆”。

    当我们在初始化一个对象,并将cls1赋给cls2的时候,其实是在stack上面创建一个栈变量,并把变量的指针指向cls1对象的引用。

    然后我们看看拆箱的过程发生了什么?

    int i=4;

    object o=i;

    int j=(int)o;

    拆箱的过程:

    (1). 检查实例:首先检查变量的值是否为null,如果是则抛出NullReferenceException异常;再检查变量的引用指向的对象是不是给定值类型的已装箱对象,如果不是,则抛出InvalidCastException异常。

    (2). 返回地址:返回已装箱实例中属于原值类型字段的地址,而两个额外成员(类型对象指针和同步块索引)则不会返回。

    到此,拆箱过程已经结束,但是伴随着拆箱,“往往”(《CLR via C#》中的描述,用的是”往往“,而并没有说一定)会紧接着发生一次字段的复制操作。

    实际上就是讲已装箱对象中的实例字段拷贝到内存栈上。

    一个自己维护的微信公众号,目前文章不多,希望接下来的日子,会一直更新下去,写自己的生活,分享技术,希望热爱生活的技术宅,一起交流!

  • 相关阅读:
    在Struts 2中使用JSON Ajax
    Android应用开发之(JSON解析库的选择)
    Unable to open log device '/dev/log/main': No such file or directory
    程序员的艺术:排序算法舞蹈
    博客园,我来迟了
    Android Service AIDL 远程调用服务之简单音乐播放实例
    Android Eclipse logcat 只显示一行的问题
    ERROR/WindowManager(***): Activity *** has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@*** that
    android布局属性详解
    Google为Android开发者提供定制的Eclipse IDE
  • 原文地址:https://www.cnblogs.com/liupeng61624/p/5130886.html
Copyright © 2011-2022 走看看