Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.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# 临时变量是一件事吗&;处理速度快吗?_C#_Variables_Memory - Fatal编程技术网

C# 临时变量是一件事吗&;处理速度快吗?

C# 临时变量是一件事吗&;处理速度快吗?,c#,variables,memory,C#,Variables,Memory,我不知道如何正确表达,所以请容忍我。在C#.NET中工作时,我继承了一个类,该类包含一个函数,该函数为非托管函数返回一个对象。当我直接使用继承的函数时,非托管任务失败。如果我创建一个对继承函数返回的对象的引用,并从引用的对象调用非托管函数,它就会工作 伪.NET代码示例: public class A { void UnmanagedFunc() {...} } public class B { public A GetA() { return new A(); } }

我不知道如何正确表达,所以请容忍我。在C#.NET中工作时,我继承了一个类,该类包含一个函数,该函数为非托管函数返回一个对象。当我直接使用继承的函数时,非托管任务失败。如果我创建一个对继承函数返回的对象的引用,并从引用的对象调用非托管函数,它就会工作

伪.NET代码示例:

public class A {
  void UnmanagedFunc() {...}
}

public class B {
  public A GetA() {
    return new A();
  }
}

public class C : B {
  public void DoSomething() {
    this.GetA().UnmanagedFunc();
  }
}

public class D : B {
  public void DoSomething() {
    var a = this.GetA();
    a.UnmanagedFunc();
  }
}
您可以看到类C和D中的函数是等价的,但是D声明了对基类函数实例化的对象的引用

我的同事们说,声明变量给了非托管进程完成的时间,因为变量的对象仍然需要被释放,而直接访问的对象被立即释放

这是有道理的,但我觉得这不是一个令人满意的答案


有人能解释这种现象吗?

如果我正确理解了你的问题,你想知道为什么会这样:

失败,而此:

没有

好吧,让我这样说:至少在非调试构建中,编译器和运行时(特别是JIT代码生成器)可以应用优化,您的局部变量
a
可能只是被优化掉了,因此出于所有实际目的,您应该假设两个版本的代码在功能上是相同的

在您给出的这样一个简单示例中,局部变量只有一个优点:它为您提供了“命名”或描述由
GetA()
返回的对象的方法;例如,您可以调用局部变量
aForRobbling
lastUsedA
,或其他任何变量

“我的同事们说,声明变量会给非托管进程一段时间来完成,因为变量的对象仍然需要处理,而直接访问的对象会立即处理。”

我不会接受这种说法,主要是因为你的同事对.NET内存管理似乎有一些错误的想法

  • 处理的不是变量,而是不再被所述变量引用的对象(或任何其他对象,如字段或参数)

  • NET中的垃圾收集(GC)是不确定的。仅仅因为变量超出范围并不意味着它上次引用的对象会立即被回收。对象(至少是堆上的对象)至少在下一个GC运行之前(无论何时)继续存在;它们是否由变量/字段/参数引用。导致对象被回收的唯一原因是它不再被任何东西引用;但您不知道GC何时启动(除非您显式触发它)

  • 术语.NET中的“Disposition”(处置)强烈表示所讨论的对象属于实现
    IDisposable
    的类型。从您的代码示例来看,这里的情况似乎并非如此

  • 话虽如此,也许我们没有看到所有相关的代码。涉及到哪些“处置”?您的非托管代码是否一直在后台运行(即在单独的线程中),并对您的.NET对象执行.NET垃圾收集器不知道的操作?不管怎样,非托管函数(
    UnmanagedFunc
    )如何成为托管对象上的方法?很多问题。除了我上面说的,我觉得我不能完全回答你的问题


    只有一件事:如果在处理对象之前确实需要给非托管代码一些时间,那么应该重新考虑程序的设计。明确时间安排,不要依赖于有时才起作用的技巧(即使这样,你也不知道为什么):非托管代码应该为你提供询问它是否成功的方法;无论是通过回调函数还是某些事件机制。如果是这样,请确保垃圾收集器在此之前不能释放.NET对象,方法是扩展其生存期范围(例如,将对象存储在类字段而不是局部变量中);或者查看
    System.Runtime.InteropServices.Marshal
    类提供给您的可能性。

    您所说的编程语言是…?对不起,我不在互联网上。我在C#工作,“它失败了”不是一个合适的问题描述。使用非托管调试器解决非托管代码的问题。如果您没有源代码,那么合适的工具是电话。伪代码在这里没有帮助。我尝试对代码进行抽象,因为它深入到为Dynamics CRM构建的框架中。非托管函数使用Web服务更新CRM实体。谢谢,我也不接受此参数,因此我发布了Stackoverflow。但我认为我需要更深入地挖掘,为正在发生的事情提供经验证据。
    this.GetA().UnmanagedFunc();
    
    var a = this.GetA();
    a.UnmanagedFunc();