C# in Depth-简单的数据类型

C# 1中定义的产品类型

以定义一个表示产品的类型作为开始,然后进行处理。

其中Product 类型内部封装了几个属性。同时还要创建预定义产品的一个列表。

//代码清单1-1
public class Product
{
    string name;
    public string Name { get { return name; } }
    decimal price;
    public decimal Price { get { return price; } }
    public Product(string name,decimal price)
    {
        this.name = name;
        this.price = price;
    }
    public static ArrayList GetSampleProducts()
    {
        ArrayList list = new ArrayList();
        list.Add(new Product("A", 1.99m));
        list.Add(new Product("B", 2.99m));
        list.Add(new Product("C", 3.99m));
        list.Add(new Product("D", 4.99m));
        return list;
    }
}

以上C# 1代码存在如下3个局限:

①ArrayList 没有提供与其内部内容有关的编译时信息。不慎在 GetSampleProducts 创建的列表中添加一个字符串是完全有可能的,而编译器对此没有任何反应。

②代码中为属性提供了公共的取值方法,这意味着如果添加对应的赋值方法,那么赋值方法也必须是公共的。

③用于创建属性和变量的代码很复杂——封装一个字符串和一个十进制数应该是一个十分简单的任务,不该这么复杂。

来看看C# 2作了哪些改进。


C# 2中的强类型集合

我们所做的第一组改动,针对上面列出的前两项,包含C# 2中最重要的改变:泛型。

//代码清单1-2
public class Product
{
    string name;
    public string Name
    {
        get { return name; }
        private set { name = value; }
    }
    decimal price;
    public decimal Price
    {
        get { return price; }
        private set { price = value; }
    }
    public Product(string name,decimal price)
    {
        Name = name;
        Price = price;
    }
    public static List<Product> GetSampleProducts()
    {
        List<Product> list = new List<Product>();
        list.Add(new Product("A", 1.99m));
        list.Add(new Product("B", 2.99m));
        list.Add(new Product("C", 3.99m));
        list.Add(new Product("D", 4.99m));
        return list;
    }
    public override string ToString()
    {
        return string.Format("{0}:{1}", name, price);
    }
}

现在属性拥有了私有的赋值方法(我们在构造函数中使用了这两个赋值方法)。

并且它能非常“聪明”地猜出 List<Product> 是告知编译器列表中只能包含 Product 。

试图将一个不同的类型添加到列表中,会造成编译时错误,并且当你从列表中获取结果时,也并不需要转换结果的类型。

C# 2解决了原先的3个问题中的2个。下面展示了展示了C# 3如何解决剩下的那个问题。


C# 3中自动实现的属性

自动实现的属性和简化的初始化,相比Lambda表达式等特性来说,有点微不足道,不过它们可以大大地简化代码。

//代码清单1-3
public class Product
{
    public string Name { get; private set; }
    public decimal Price { get; private set; }
    Product() { }
    public static List<Product> GetSampleProducts()
    {
        return new List<Product>()
        {
            new Product{Name="A", Price=1.99m},
            new Product{Name="B", Price=2.99m},
            new Product{Name="C", Price=3.99m},
            new Product{Name="D", Price=4.99m}
        };
    }
    public override string ToString()
    {
        return string.Format("{0}:{1}", Name, Price);
    }
}

不再有任何代码、可见的变量与属性关联,而且硬编码的列表是以一种全然不同的方式构建的。

由于没有 name 和 price 变量可供访问,我们必须在类中处处使用属性,这增强了一致性。

现在有一个私有的无参构造函数,用于新的基于属性的初始化。(设置这些属性之前,会对每一项调用这个构造函数。)

在本例中,实际上可以完全删除旧的公共构造函数。但这样一来,外部代码就不能再创建其他的产品实例了。


C# 4中的命名实参

对于C# 4,涉及属性和构造函数时,我们需要回到原始代码。

其中有一个原因是为了让它不易变:尽管拥有私有赋值方法的类型不能被公共地改变,但如果它也不能被私有地改变,将会显得更加清晰。

不幸的是,对于只读属性,没有快捷方式,但C# 4允许我们在调用构造函数时指定实参的名称,

如下所示,它为我们提供了和C# 3的初始化程序一样的清晰度,而且还移除了易变性(mutability)。

//代码清单1-4
public class Product
    {
        readonly string name;
        public string Name { get { return name; } }
        readonly decimal price;
        public decimal Price { get { return price; } }
        public Product(string name,decimal price)
        {
            this.name = name;
            this.price = price;
        }
        public static List<Product> GetSampleProducts()
        {
            return new List<Product>()
            {
                new Product(name:"A", price:1.99m),
                new Product(name:"B", price:2.99m),
                new Product(name:"C", price:3.99m),
                new Product(name:"D", price:4.99m)
            };
        }
        public override string ToString()
        {
            return string.Format("{0}:{1}", Name, Price);
        }
    }

在这个特定的示例中,该特性的好处不是很明显,但当方法或构造函数包含多个参数时,它可以使代码的含义更加清楚——特别是当参数类型相同,或某个参数为 null 时。

当然,你可以选择什么时候使用该特性,只在使代码更好理解时才指定参数的名称。

图1-1总结了 Product 类型的演变历程。注意,图中没有涉及C# 5。这是因为C# 5主要特性(异步函数)面向的领域还没有太多的语言支持。稍后,我们将简单看一下。

到目前为止,变化幅度都不大。事实上,泛型的加入( List<Product> 语法)或许是C# 2最重要的一个部分。

我们现在只看到了它的部分用处,不过这只是刚刚开始。下一个任务是以字母顺序打印产品列表。

原文地址:https://www.cnblogs.com/errornull/p/10014941.html