区块链技术博客
www.b2bchain.cn

调用动作-确定它所属的实例是否为空 – c#程序员分享

本文介绍了调用动作-确定它所属的实例是否为空 – c#程序员分享,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

我有一个方法,将Action作为参数。操作将存储在队列中,并在特定资源可用时执行。在调用动作之前,我想检查它所属的实例是否为null。

我用下面的愚蠢的例子做了一个简单的测试。将被调用方设置为null后,成功调用了Action,并且按预期,当尝试访问null被调用方的属性时,我得到了NullReferenceException。在检查运行时的Action时,什么都没想到,我建议我可以确定其实例是否为空。

我想我可以将Action和实例作为参数传递,并在调用之前测试实例是否为null。是否有可能测试null调用,或者这仅仅是我设计不好的一种情况?

更新:

我加了线

如果(explosion.Target!= null)

到Bazooka.Fire(),以检查是否为空目标,但在我的示例中它仍在调用委托。

public void LetsDoThis()     {         var bazooka = new Bazooka();         var rocketLauncher = new RocketLauncher();          bazooka.LockAndLoad(rocketLauncher.BlowStuffUp);          rocketLauncher = null;          bazooka.Fire();          bool wasThisCompletelyAwesome = rocketLauncher.ThisIsAwesome;     }  public class RocketLauncher     {         public void BlowStuffUp()         {             bool stuffIsBlowingUp = true;         }          public bool ThisIsAwesome         {             get             {                 return true;             }         }     }  public class Bazooka     {         private List<Action> explosions = new List<Action>();          public void LockAndLoad(Action loadIt)         {             this.explosions.Add(loadIt);         }          public void Fire()         {             foreach (Action explosion in explosions)                 if (explosion.Target != null)                     explosion.Invoke();         }     } 

参考方案

这行不通。

Action完全不关心您从中获取的原始参考变量,它会复制参考值,因此具有自己的参考。

请注意,这还意味着,即使您没有对原始对象的其他引用,只要您仍然有对委托的引用,它仍将不符合垃圾回收的条件。

.Target属性是指应在其上调用委托所引用的方法的实例,基本上是该方法的this“参数”。

因此,要具有null目标,您需要从静态方法获取委托,请在LINQPad中尝试以下操作:

void Main() {     Action a = Static.StaticMethod;     (a.Target == null).Dump(); }  public static class Static {     public static void StaticMethod() { } } 

您可以看到委托使用以下LINQPad代码携带自己的实例:

void Main() {     Dummy d = new Dummy { Name = "A" };     Action a = d.Method;      d = new Dummy { Name = "B" };     Action b = d.Method;      d = null;      a();     b(); }  public class Dummy {     public string Name { get; set; }     public void Method()     {         Debug.WriteLine("Name=" + Name);     } } 

这里的输出将是

Name=A Name=B 

根据要求,让我澄清一下实例,引用和变量之间的区别。

在构造对象实例时,如下所示:

var rocketLauncher = new RocketLauncher(); 

您正在做的是调用一个称为构造函数的方法。该构造函数的返回值是对新构造对象的引用。基本上,它是一个指针,表示对象现在在内存中所处位置的内存地址。如果它更容易理解此答案的其余部分,则可以认为它只是一个数字。

此外,您还声明了一个变量rocketLauncher,以保存此引用和此数字。

请注意,对象与变量是分开的,它们是两个不同的项目。在内存中的一个位置,您有一个对象,在另一位置,您具有包含对该对象的引用的变量,即地址,编号。

因此,当您执行此操作时:

bazooka.LockAndLoad(rocketLauncher.BlowStuffUp); 

让我们简化一下:

Action a = rocketLauncher.BlowStuffUp; // bazooka.LockAndLoad(a); 

让我们忘了调用LockAndLoad方法的那一部分,看看当我们将方法BlowStuffUp“转换”为类型为Action的委托时发生了什么。

基本上,有两件事是“被抓住的”:

委托代表使用哪种方法
在其上调用该方法的对象实例

您可以将其比作以下代码:

MethodReference = rocketLauncher.BlowStuffUp; object target = rocketLauncher; // wrap this into a delegate 

现在这意味着您对该对象有两个引用,一个引用位于rocketLauncher变量中,另一个引用位于委托中。

您对该变量执行的操作不会以任何方式更改该委托的值,它仍指向与以前相同的对象。基本上,它复制了该号码。该号码仍坐在代表内部。

这几乎完全相同:

int a = 10; int b = a; a = 0; // b is still 10 

因此,总而言之,委托的.Target属性完全不知道或关心您从其中获取委托的原始变量。将原始变量的参考值复制到委托中,之后对变量的操作完全没有区别。

所以基本上:

实例是对象,它存在于内存中的某个位置
引用基本上是它的地址,您可以将其视为一个数字
该变量是您可以存储该引用的地方

现在,如果您真的想让委托依赖于变量,并在调用它时关心它现在具有的值,该怎么办?

好吧,一种方法是这样做:

bazooka.LockAndLoad(delegate {     if (rocketLauncher != null)         rocketLauncher.BlowStuffUp(); }); 

这将创建一个匿名方法,该方法将捕获变量本身,然后在该匿名方法内部,您可以在调用委托时显式检查变量具有的值。如果关于匿名方法的这部分没有意义,那么您应该在这里提出另一个问题(最好是在阅读了一些有关匿名方法,捕获变量并在SO上查看了一些现有问题之后)。

要测试匿名方法,请在LINQPad中测试以下代码:

void Main() {     object dummy = new object();     Action a = delegate     {         if (dummy != null)             Debug.WriteLine("not null");         else             Debug.WriteLine("null");     };      a();     dummy = null;     a(); } 

它将打印出:

not null null 

可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制

这个是我刚毕业的时候,一个真实的面试题,这是一个开放题。题目描述:想办法,将一个城市的所有灯泡数量统计出来。题解:费米估算法1、如果某个城市常驻人口有1000万2、假设每5人居住在一套房里,每套房有灯泡5只,那么住宅灯泡共有1000万只3、假设公众场所每10人共享一只灯泡,那么共有100万只4、主要的这两者相加就得出了1100万只当然实际上这是估算的,具体应…

一个圆盘被涂上了黑白二色,两种颜色各占一个半圆。圆盘以一个未知的速度、按一个未知的方向旋转。你有一种特殊的相机可以让你即时观察到圆上的一个点的颜色。你需要多少个相机才能确定圆盘旋转的方向?题解:可以用一个相机即可

来自字节跳动的一道几何题题解:1/4

深度优先遍历的范围更大还是回溯的范围更大?为什么?题解:我的理解是:dfs是回溯思想的一种体现- 回溯:是在整个搜索空间中搜索出可行解,在搜索过程中不断剪枝回退,这是回溯的思想,这个搜索空间并没有限制于特定的数据结构。- dfs:dfs是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 调用动作-确定它所属的实例是否为空 – c#程序员分享
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们