图片 13

选用质量升高MyBank,无参属性

做项目时偶尔B类赋值给A类,碰巧A和B类型很多属性字段名是一样的,或者只是大小写不一样,这是可以利用泛型,反射来写一个自动化赋值的方法。

提起属性,我们都不陌生。它用起来就像访问public数据成员一样,但实际上是调用了内部定义的相应方法。通过使用属性保持了较好的数据封装,而且访问很方便,接下来我们共同复习以下CLR允许定义的两种属性:无参属性和有参属性(索引器)。

使用属性升级MyBank

下面方法不考虑大小写不一样的情况,如果要考虑,可以使用字符串方法
ToUpper() 、ToLower() 后,对比字段名是否一样。


访问修饰符

 public class MapperModel
    {
        /// <summary>
        /// B对象相同属性赋值给A对象, 
        /// </summary>
        /// <typeparam name="A">类型A</typeparam>
        /// <typeparam name="B">类型B</typeparam>
        /// <param name="b">B对象</param>
        /// <returns>返回创建的新A对象</returns>
        public static A Mapper<A, B>(B b)
        {
            A a = Activator.CreateInstance<A>();
            try
            {
                Type Typeb = b.GetType();//获得类型  
                Type Typea = typeof(A);
                foreach (PropertyInfo bp in Typeb.GetProperties())//获得类型的属性字段  
                {
                    foreach (PropertyInfo ap in Typea.GetProperties())
                    {
                        if (ap.Name == bp.Name)//判断属性名是否相同  
                        {                          
                            if (ap.GetSetMethod()!= null)
                            {
                                if (bp.GetGetMethod()!=null)
                                {
                                    ap.SetValue(a, bp.GetValue(b, null), null);//获得b对象属性的值复制给a对象的属性   }
                                }

                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return a;
        }
    }

一、 无参属性

Java中的访问修饰符

值得注意的地方,属性到底有没有Get或者Set方法 ?B属性Set访问器是非公共的或不存在
则会赋值时出现异常。同理:A属性如果 Get
访问器是非公共的或不存在,则取值时出现异常

1. 定义属性

无参属性就是我们最常见的属性方式,在赋值时可以加入一定的逻辑判断。属性的定义其实不复杂,先看个直观的例子:

图片 1

说明:

  • 属性要定义名称和类型,且类型不能是void。
  • 属性是不能重载的。我们不能定义名称相同、类型不同的两个属性。
  • 属性一般需要定义get和set方法来操作类内部的私有支持字段,如上面的_name,
    _age等。Set方法中包含隐藏参数叫做value,表示赋给属性的值。
  • 只读只写属性:可以通过省略set来定义只读属性(如Count属性),或者省略get来定义只写属性。
  • CLR支持静态、实例、抽象和虚属性。例子中的Name和Age就是我们最常用的实例属性,Count就是静态只读属性的例子。

调用:使用属性时会产生相应的智能感知,就像使用公用字段一样:

图片 2

运行结果:

图片 3

Public 、protected、private

因此上面使用了 GetSetMethod(),GetGetMethod()做判断。如果Get 、Set
访问器不能正常获取,则返回为null。

2. 编译结果

通过ILDasm.exe查看元数据,

图片 4

我们发现多了以下几项:

① 如果属性包含get访问器,则会生成“get_属性名
的方法,如get_Age;

② 如果属性包含set访问器,则会生成“set_属性名”的方法,如set_Name;


元数据中的属性定义项,包含了一些标记和属性类型,并引用了get或set访问器方法,这样就使属性和访问器之间产生了关联。例如Count属性定义项内容:

   
图片 5

 

 

3. 自动实现的属性——AIP

AIP(Automatically Implemented
Property)是实现属性的一种更简洁的方式。例如上面的Student类,可以简化为:

图片 6

调用方式和运行结果与之前一致,这里就不赘述了。

简洁固然好,但要注意以下几点:

① AIP的get和set方法中不能添加断点调试。


AIP属性必须是同时可读可写的。如果只定义get或者只定义set,则必须两个都显式实现,不能使用AIP。


想要序列化或者反序列化的类中,不要定义AIP。因为运行时序列化引擎将字段名持久化到了序列化流中,而且每次编译时这个名字还有可能改变。

C#

感觉下面的代码写法更可读:省略了一个循环

二、 有参属性——索引器

索引器是访问器包含参数的属性, C#是以数组的风格来公开索引器的。

Public公共的                     访问级别最高

        /// <summary>
        /// 传入类型B的对象b,将b与a相同名称的值进行赋值给创建的a中        
        /// </summary>
        /// <typeparam name="A">类型A</typeparam>
        /// <typeparam name="B">类型B</typeparam>
        /// <param name="b">类型为B的参数b</param>
        /// <returns>拷贝b中相同属性的值的a</returns>
        public static A MapperTwo<A, B>(B b)
        {
            A a = Activator.CreateInstance<A>();
            try
            {
                Type Typeb = typeof(B);//获得类型  
                Type Typea = typeof(A);               
                foreach (PropertyInfo ap in Typea.GetProperties())
                {
                    System.Reflection.PropertyInfo bp = Typeb.GetProperty(ap.Name); //获取指定名称的属性
                    if (bp != null) //如果B对象也有该属性
                    {
                        if (ap.GetSetMethod() != null) //判断A对象是否有能用Set方法
                        {
                            if (bp.GetGetMethod() != null) //判断B对象是否有能用Get方法
                            {
                                ap.SetValue(a, bp.GetValue(b, null), null);//获得b对象属性的值复制给a对象的属性   
                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return a;
        }
1. 定义索引器。

图片 7


和无参属性类似,索引器也需要定义get,set访问器,并且在set访问器中可以使用value关键字。不同的是,索引器的get访问器需要接受参数。

② 要使用this关键字定义索引器。

调用:索引器使得对象可按照与数组相似的方法进行索引。

图片 8

图片 9

Private私有的                  访问级别最低

 

2. 编译结果

查看ILDasm.exe。

图片 10

编译之后与无参属性类似,只不过编译器为访问器采用了默认名称Item:

① 如果索引器包含get访问器,则会生成“ get_Item” 的方法;

② 如果索引器包含set访问器,则会生成“set_Item”的方法;

③ 元数据中的属性定义项。

 

估计我写的就是下面的原理,序列化,反序列化,不区分大小写。当然,不能否定上面的内容。

3. 注意事项


默认产生的Item名称是可以修改的。可以通过向索引器添加“IndexerName”的attribute来实现。例如:

图片 11

图片 12


索引器可被重载。在C#中,一个类可以定义多个索引器,只要索引器的参数集不同即可。

③ 索引器可以有多个形参,例如当访问二维数组时。

图片 13

④ 索引器只能用于实例,不能用于静态。


THE END。

终于写完了。饿死了,吃饭,回家。

访问修饰可以用来修饰字段(属性)和方法,用来限定类成员的访问级别

public static A MapperTwo<A, B>(B b)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<A>(Newtonsoft.Json.JsonConvert.SerializeObject(b));
        }

Student stu = new Student();

 

stu.userName = “”;

stu.age = 0;

stu.show1();

stu.show2();

private string userName = “Tom”;

public int age = 18;

 

 

public void show1()

{

    Console.WriteLine(“AAAAA”);

}

 

private void show2()

{

    Console.WriteLine(“AAAAA”);

   

}

 

This关键字(指定当前对象)

C#所有的对象都将创建在并脱管堆上

/// <summary>

/// 初始化学员

/// </summary>

/// <param name=”name”></param>

public void SetName(string name)

{

    this.userName = name;

}

 

public void Show()

{

Console.WriteLine(“大家好:{0},今年:{1}”,this.userName,this.age);

 

}

 

 

C#属性

1)  一个物体抽象出来,形成公共的类,减少代码量

2)  用方法保证数据的安全

 

做一个年龄的限制

private int age;

public string idCard;

 

/// <summary>

/// 得到年龄

/// </summary>

/// <returns></returns>

public int GetAge()

{

    // 返回值

    return this.age;

}

 

public void SetAge(int age)

{

    if (age < 0 || age > 100)

    {

        this.age = 19;

    }

    else

    {

        this.age = age;

    }

}

测试类

Student stu = new Student();

 stu.SetAge(-10);

 Console.WriteLine(“年龄是:{0}”,stu.GetAge());

 

 stu.SetAge(35);

 Console.WriteLine(“年龄是:{0}”, stu.GetAge());

 

 Console.ReadKey();

 

用属性实现字段的封装

private string UserName;

快捷键(Ctrl + r + e)

Get访问器用来返回相应私有的字段属性,get访问器与方法相似,必须使用return返回字段值

 

Set访问器用来设置相应私有字段的值,set访问器类似于返回类型为void的方法

 

public int Age

{

    get

    {

        return age;

    }

    set

    {

        if (value < 0 || value > 100)

        {

            this.age = 19;

        }

        else

        {

            this.age = value;

        }

    }

}

属性的数据类型

定义一个类中的属性,属性的数据类型必须与他所范文的字段类型一致(必须是整形)

属性的类型可以是一个类或者一个数组

 

属性的访问类型

属性访问类型分为三种:

1)  只读属性:只有Get

2)  只写属性:只有Set

3)  只读只写:Get+Set

 

字段和属性的区别?

        
通常字段是指private,在类的内部使用。讲指定属性为public,对外开发个,同常get或set提供访问安全,有效的范围保护

 

C#中的属性和方法?

C#中的属性set访问器和get访问器后面不能加“()”,因为访问器没有返回值

 

对象初始化

先创建一个Student对象在初始化

Stu.userName = “某某”;

 

对象初始化

Student stu = new Student(){username = “某某”};//
多个属性之间使用“逗号”隔开

 

 

面向对象(封装、继承、多态)

 

C#中—–封装

什么是封装:就是将东西打包

          作用:隐藏类的内部细节,只对外暴露类的基本操作

好处:

1)  避免非法数据的赋值

2)  保证数据的完整性

3)  避免类内部发生修改时,导致整个程序发生变化

 

通过访问修饰符来实现

Public:公共的

Private:私有的

Protected:只有该类对象(自己)及子类对象可以访问(继承关系)

Internal:同一个程序集的对象可以访问

Protected Internal:访问限于当前程序集或派生自包含类的类型

                  
比如说:一个人A为父亲,他的儿子B,妻子C,私生子D(注:D不在他家)

                   Public:地球人都知道,公开的

Private:只有A知道(隐私、私事,心事)

                  
Protected:A,B,D(A和他所有儿子都知道,C他妻子不知道)

                   Internal:A,B,C知道(私生子D不知道)

                   Protected Internal:A,B,C,D都知道,其他人不知道

 

值传递和引用传递

 

Java中是如何数据传给方法的,通过参数的形式

int pay;// 税前工资

float taxRate = 0.1f;// 税率

float afterTax;//税后工资

Console.WriteLine(“请输入税前工资:”);

pay = int.Parse(Console.ReadLine());

if (pay <= 3500)

{

    afterTax = pay;

}

else

{

    afterTax = pay – (pay – 3500) * taxRate;

}

Console.WriteLine(“税前工资{0}n税后工资{1}”,pay,afterTax);

Console.ReadKey();

 

修改后的

private static float GetPay(int pay, float taxRate)

{

    float after;// 税后的工资

    if (pay <= 3500)

    {

        after = pay;

    }

    else

    {

        after = pay – (pay – 3500) * taxRate;

    }

 

return after;

 

以上是值传递

 

java中左右手换纸牌

三个abc

 

 

实现左右手换纸牌

引用传递

要想实现左右手换纸牌需要按引用传递的方式进行(需要使用ref关键字)

 

值传递(拿的是复制品)

值传递是将变量的值复制了一份,是方法的形参和实参的值相同,在调用方法中修改形参也只是对复制品做修改,并没有真正的改变实际参数的值

 

引用传递(拿的是原来参数的地址    关键字ref)

        
引用传递是将传递的对象引用复制给方法的形参,使被调用的方法直接对引用对象进行更改,会影响到原来的值

                       

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注