我有以下课程:
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { set; get; }
}
public class LinqValueCalculator
{
public decimal ValueProducts(IEnumerable<Product> products)
{
return products.Sum(p => p.Price);
}
}
public class ShoppingCart
{
private LinqValueCalculator calc;
public ShoppingCart(LinqValueCalculator calcParam)
{
calc = calcParam;
}
public IEnumerable<Product> Products { get; set; }
public decimal CalculateProductTotal()
{
return calc.ValueProducts(Products);
}
}
在ShoppingCart类中,根据我的理解private LinqValueCalculator calc;
我们正在从该类创建一个对象,但这与private LinqValueCalculator calc = new LinqValueCalculator();
应该首选哪一个......在哪里以及为什么?
答案 0 :(得分:7)
在ShoppingCart类中,有私有的LinqValueCalculator calc;根据我的理解,我们正在从该类创建一个对象
不,它没有。它声明了该类型的变量,但它不会创建任何对象。最初,这将默认为null
...但对differentiate between objects, variables and references来说非常重要。例如,您可以有两个变量但只有一个对象......
LinqValueCalculator calc1 = new LinqValueCalculator();
LinqValueCalculator calc2 = calc1;
这里两个变量具有相同的值 - 这是对它创建的单个对象的引用。
答案 1 :(得分:6)
在下面的代码中,您将课程calc
中的参考ShoppingCart
分配给calcParam
中传递的参考。最初calc
字段为null
,一旦构造函数运行,它就会分配给calcParam
。两个引用都指向同一个对象,因此任何引用都会在对象中反映出更改。
private LinqValueCalculator calc;
public ShoppingCart(LinqValueCalculator calcParam)
{
calc = calcParam;
}
下面的代码创建了一个仅从此类引用的新LinqValueCalculator
对象。没有其他人对此对象有引用,因此只有购物车才能使用该对象。
private LinqValueCalculator calc = new LinqValueCalculator();
根据您是否需要共享计算器以及是否要在ShoppingCart
类中控制其生命周期,这两种用法都很有用。
如果您有C ++背景,C#引用更像是C ++指针而不是引用。
因此假设LinqValueCalculator
有默认构造函数,创建ShoppingCart
可能如下所示:
LinqValueCalculator calc = new LinqValueCalculator();
ShoppingCart cart = new ShoppingCart(calc);
答案 2 :(得分:1)
这只是一个架构决策。将LinqValueCalculator
作为参数放在ShoppingCard
构造函数中的原因是因为作者想要使用依赖注入。当您使用DI时,您将对象的生命周期的责任移到ShoppingCard
类之外,这将在未来提供更多控制,因为每个对象都从外部接收它的依赖关系,但它们只消耗它,没有实例化。
这使得遵循单一责任原则变得容易。通常,另一个名为composer或catalog的对象负责实例化所有依赖项并将它们提供给对应的对象。