Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Don';你不需要一个对象名来传递给构造函数吗&引用;新类();isn';我还没找到目标_C#_Object_Inheritance_Composition - Fatal编程技术网

C# Don';你不需要一个对象名来传递给构造函数吗&引用;新类();isn';我还没找到目标

C# Don';你不需要一个对象名来传递给构造函数吗&引用;新类();isn';我还没找到目标,c#,object,inheritance,composition,C#,Object,Inheritance,Composition,我一直在用我的一些课程来补充我的学校课程。我现在正试图理解中间C#的一个例子,我对其中的一个细节有点困惑。我理解继承,但对组合(特别是将对象传递给对象以及在哪里初始化对象)有点困惑。在本例中,有一个DbMigrator类、安装程序类和一个记录器类,DbMigrator和安装程序都从中借用。主要内容如下: namespace Composition { class Program { static void Main(string[] args)

我一直在用我的一些课程来补充我的学校课程。我现在正试图理解中间C#的一个例子,我对其中的一个细节有点困惑。我理解继承,但对组合(特别是将对象传递给对象以及在哪里初始化对象)有点困惑。在本例中,有一个DbMigrator类、安装程序类和一个记录器类,DbMigrator和安装程序都从中借用。主要内容如下:

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();