C#:显示属性与自动实现(隐式)属性的区别

  1. 自动实现属性 (public Product ZhuangHeZi { get; set; }):

    • 这是C#中自动实现属性的一种方式。编译器会自动生成一个私有字段来存储这个属性的值。
    • 使用这种方式,你不需要手动编写字段和访问器的实现,编译器会为你处理。这使得代码更加简洁。
    • 例如,当你使用 box.ZhuangHeZi = p; 时,编译器会自动将 p 的值存储到编译器生成的私有字段中。同样地,当你访问 box.ZhuangHeZi 时,编译器会自动返回该私有字段的值。
  2. 显式实现属性:必须声明私有字段,不然会无限递归

    • 这部分代码试图显式地实现一个属性,但缺少一个属性的私有字段,导致无限递归的问题。
    • get { return ZhuangHeZi; } 和 set { ZhuangHeZi = value; } 这两行代码试图返回和设置 ZhuangHeZi 自身的值,而不是编译器生成的私有字段。
    • 这会导致无限递归调用,因为每次访问或设置 ZhuangHeZi 的值时,都会调用属性的 get 或 set 访问器,而这些访问器又试图访问或设置 ZhuangHeZi 的值。
class Box {
    public Product ZhuangHeZi{ get; set; }//自动实现属性的声明


    //【【注意】】:显示实现属性,一定要有声明的私有字段,不然会导致无限递归
    private Product zhuangHeZi; // 添加私有字段
    public Product ZhuangHeZi //显示实现属性
    {
        get { return ZhuangHeZi; }
        set { ZhuangHeZi = value; }
    }

}

错误案例源代码:

namespace Class007_delegateWetTuo_MuBanFangFa
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ProductFactory pf = new ProductFactory();
            Func<Product> fun = new Func<Product>(pf.MakeSu7);
            BaoZhuangFactory bzf = new BaoZhuangFactory();
            Box su7Box = bzf.BaoZhuang(fun);
            Console.WriteLine(su7Box.ZhuangHeZi.Name);
        }
    }

    class BaoZhuangFactory {
        public  Box BaoZhuang(Func<Product> func){
            Box box = new Box();
            Product p = func.Invoke();
            box.ZhuangHeZi = p;
            
            return box;
        }
    }
    class Product
    {
        public string Name { get; set; }
    }
    class Box {
        //public Product ZhuangHeZi{ get; set; }


        public Product ZhuangHeZi //这里想要显示属性替代隐式属性,以发现二者差别,结果出错了
        {
            get { return ZhuangHeZi; }
            set { ZhuangHeZi = value; }
        }

    }
    class ProductFactory {
        public Product MakePizza() { 
        
            Product p = new Product();
            p.Name = "A pizza";
            return p;
        }
        public Product MakeSu7()
        {
            Product p = new Product();
            p.Name = "xiaomi Su7";
            return p;
        }
    }
}

AI给的解析与解决方案:

public Product ZhuangHeZi{ get; set; } public Product ZhuangHeZi { get { return ZhuangHeZi; } set { ZhuangHeZi = value; } }这两处代码的区别

引用信息 Program.cs 29:36

在这段代码中,public Product ZhuangHeZi { get; set; } 和下面的显式实现 public Product ZhuangHeZi 的代码块是重复的,并且会导致无限递归的问题。让我们详细解析一下两处代码的区别和问题:

  1. 自动实现属性 (public Product ZhuangHeZi { get; set; }):

    • 这是C#中自动实现属性的一种方式。编译器会自动生成一个私有字段来存储这个属性的值。
    • 使用这种方式,你不需要手动编写字段和访问器的实现,编译器会为你处理。这使得代码更加简洁。
    • 例如,当你使用 box.ZhuangHeZi = p; 时,编译器会自动将 p 的值存储到编译器生成的私有字段中。同样地,当你访问 box.ZhuangHeZi 时,编译器会自动返回该私有字段的值。
  2. 显式实现属性 (public Product ZhuangHeZi):

    • 这部分代码试图显式地实现一个属性,但存在无限递归的问题。
    • get { return ZhuangHeZi; } 和 set { ZhuangHeZi = value; } 这两行代码试图返回和设置 ZhuangHeZi 自身的值,而不是编译器生成的私有字段。
    • 这会导致无限递归调用,因为每次访问或设置 ZhuangHeZi 的值时,都会调用属性的 get 或 set 访问器,而这些访问器又试图访问或设置 ZhuangHeZi 的值。

解决方法

如果使用显式实现,应该为属性添加一个私有字段,并在这个字段上进行 get 和 set 操作。例如:

class Box {
    private Product zhuangHeZi; // 添加私有字段

    public Product ZhuangHeZi {
        get { return this.zhuangHeZi; } // 使用私有字段
        set { this.zhuangHeZi = value; } // 使用私有字段
    }
}

在上述代码中,zhuangHeZi 是用于存储 ZhuangHeZi 属性值的私有字段。这样,get 和 set 访问器就会正确地操作这个字段,而不是导致无限递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值