C# Don';你不需要一个对象名来传递给构造函数吗&引用;新类();isn';我还没找到目标
我一直在用我的一些课程来补充我的学校课程。我现在正试图理解中间C#的一个例子,我对其中的一个细节有点困惑。我理解继承,但对组合(特别是将对象传递给对象以及在哪里初始化对象)有点困惑。在本例中,有一个DbMigrator类、安装程序类和一个记录器类,DbMigrator和安装程序都从中借用。主要内容如下:C# Don';你不需要一个对象名来传递给构造函数吗&引用;新类();isn';我还没找到目标,c#,object,inheritance,composition,C#,Object,Inheritance,Composition,我一直在用我的一些课程来补充我的学校课程。我现在正试图理解中间C#的一个例子,我对其中的一个细节有点困惑。我理解继承,但对组合(特别是将对象传递给对象以及在哪里初始化对象)有点困惑。在本例中,有一个DbMigrator类、安装程序类和一个记录器类,DbMigrator和安装程序都从中借用。主要内容如下: namespace Composition { class Program { static void Main(string[] args)
namespace Composition
{
class Program
{
static void Main(string[] args)
{
var dbMigrator = new DbMigrator(new Logger());
var logger = new Logger();
var installer = new Installer(logger);
dbMigrator.Migrate();
installer.Install();
}
}
}
我理解您创建一个logger对象并将其传递给installer对象的部分,但是我没有得到dbMigrator对象的“new logger()”构造函数,因为正在创建的logger没有变量名。您不需要在dbMigrator对象的构造函数中创建“var logger1=new Logger()”吗?我不明白你怎么能在没有变量名的情况下传递“newlogger()”
以下是DbMigrator类:
namespace Composition
{
public class DbMigrator
{
private readonly Logger _logger;
public DbMigrator(Logger logger)
{
_logger = logger;
}
public void Migrate()
{
_logger.log = ("Blah blah blah");
}
}
}
我意识到DbMigrator类已经初始化了一个,但我认为需要首先创建一个对象
有人能帮我澄清一下吗?首先,总结一下这个问题——这是怎么回事
var dbMigrator = new DbMigrator(new Logger());
不应该是这样吗
var logger = new Logger();
var dbMigrator = new DbMigrator(logger);
一个完整详细的答案相当长,所以我会尽我最大的努力使它很好和容易遵循。我们将首先描述什么是表达式以及它们在C#中如何工作(更广泛地说,它们在任何基于堆栈的语言中如何工作——幸运的是,这几乎是您所听说过的所有语言!)
表达式、语句和操作。。什么?
一种操作:类似于加法、减法等
表达式:一组操作1+2+3
或像1
或“嗨!”
语句:通常是一个表达式后跟一个
但类似于if
或while
循环的语句也是语句。如果一个程序是一个烹饪食谱,那么一个语句就是其中的一个步骤
让我们快速看一下C#中的这一点:
这是一条语句,它被分解为如下操作:
- 2乘以3
- 加1
- 将结果设置为名为
totalPrice
将2乘以3之后,6存储在哪里
回答:堆栈。稍后将详细介绍
关于方法的快速附加说明
方法调用,比如Hello(“all!”)代码>接受表达式作为参数<代码>你好(1+1;)代码>失败,因为其中有一条语句<代码>你好(1+(2*3))代码>很好
操作
每个操作接受任意数量的操作数,然后有选择地输出某些内容。例如,乘法运算接受2个操作数-A*B,然后输出它们相乘的结果newsomething()
接受任意数量的构造函数参数并输出对新创建对象的引用
这是最重要的部分
操作的输出总是进入堆栈。输入也总是先放在堆栈上。
那么这堆东西是什么?
此处不包含完整信息-如果您对完整信息感兴趣,请查看,例如。快速总结是所有基于C的语言都使用相同的概念。让我们回顾一下上面的C#语句,并在堆栈操作中描述它:
int totalPrice=1+2*3;
- 将2推到堆栈上
堆栈现在仅为[2]
- 将3推到堆栈上
堆栈现在为[2,3]
- 相乘(从堆栈中弹出两个值并相乘)
堆栈现在是[6]
- 将1推到堆栈上
堆栈现在为[6,1]
- Add(从堆栈中弹出两个值,将它们相加)
堆栈现在是[7]
- 存储在本地
totalPrice
(弹出堆栈值并存储)
堆栈现在为空
旁注:这些堆栈操作是C#编译器生成的。它叫
调用堆栈
健康警告调用堆栈完全不同。调用堆栈可能会“溢出”
原始声明怎么样?
好吧,希望我们已经为这部分做了足够的铺垫,让它更有意义!让我们看一下原始的陈述:
var dbMigrator = new DbMigrator(new Logger());
首先,new
操作与任何其他方法调用一样—所有参数都被推送到堆栈上,方法被调用(将它们全部从堆栈中弹出),然后返回值被放在堆栈上
因此,这里描述的是堆栈样式:
- 新建Logger对象(在堆上创建一个Logger对象,并在堆栈上放置对该对象的引用。无参数,因此不会弹出任何内容)
堆栈现在是[记录器参考]
- 新的DBMigrator对象(关闭1参数,推送引用)
堆栈现在是[DBMigrator引用]
- 存储在本地
dbMigrator
堆栈现在为空
要真正实现这一点,请将其与备选方案(同样有效)进行比较:
- 新的记录器对象
堆栈现在是[记录器参考]
- 存储在本地
记录器中
堆栈现在为空
- 加载本地
记录器
堆栈现在是[记录器参考]
- 新的DbMigrator对象
堆栈现在是[DBMigrator引用]
- 存储在本地
dbMigrator
堆栈现在为空
你刚刚学到的:它们都能工作,但第二个稍微慢一点——它能做得更多。看看那些堆栈操作,它似乎做了一些完全没有意义的事情——就像你只是把一些东西放进了一个文件柜
var dbMigrator = new DbMigrator(new Logger());
var logger = new Logger();
var dbMigrator = new DbMigrator(logger);
Logger logger=new Logger();
// Using it twice!
logger.A();
logger.B();
(new Logger()).A();
(new Logger()).A().B();