Something about overloads

 

delegate void MyInvoker();

void Test(MyInvoker Invoker,  int SomeOthers)
{
 //... codes here
}

void Test(object DefaultValue, int SomeOthers)
{
 //... codes here
}

Test(null, 1);


对于这样一个代码,大家说说看会调用哪一个函数?答案是delegate的版本。这个跟函数出现的顺序无关,而跟调用重载函数的猜测规则有关。这个规则要求在匹配的情况下,尽可能的使用更为特殊的版本。而对于null来说,任何的class都是适合的(不包括valuetype和struct),而delegate是从object派生出来的,因此编译器就选择了delegate的版本。那好,如果我要用null作为参数调用object版本怎么办?办法有两个:
1、在Test(MyInvoker ...) 函数里面判断Invoker==null,跳转Test(object...)版本。
2、Test( (object) null, ...);

实际上第一个办法里面的跳转,还是要依赖于第二个办法,只是不需要每一个调用都这么写。但是带来了方便的同时,也带来了损失性能的后果,尽管并不是很严重。如果你认为性能非常重要,甚至连这么一句判断都是不可容忍的,同时也不希望每次调用都要多写一个(object)来限定调用的版本,那么我建议你不要用重载,直接把这个版本的函数换一个名字,例如TestObject(object DefaultValue, ...)。

到这里事情还没有结束,我们再添加一个函数:

void Test(Label DefaultValue, int SomeOthers)
{
 //... codes here
}


然后我们仍然使用Test(null, 1)来测试,结果却发现编译错误,对吧?因为Label和delegate之间不是派生和继承关系,而是类似兄弟或者叔叔之类的关系。同样的,如果你有一个Label和ToolBar的版本,编译也是通不过的,这个时候你只好添加一个(Label)之类的强制转换来指定调用的版本。不过实际上也只有null才会有如此麻烦的问题,而对于其它的任何东西都没有这个问题。原因很简单,只有null才是任何引用类型都能够接受的,同时也不知道属于哪一个类型的。有人就会想到另外一个情况了:

object o = null;
Test(o, ...);

假设现在有object、Label、ToolBar三个版本,会不会编译错误呢?答案是不会的,并且你会发现它调用了object的版本。原因是版本判断规则并不关心变量里面的实际内容是什么,只关心这个变量声明成什么类型了。由于这里的o是声明为object,因此自然调用的是object版本的函数,这个和(object)强制转换没有什么区别。也许你就会想到本文最前面提到的两个解决方法,现在这个就应该是第三个。没错,这也是一种办法,但是它既没有第一种方法的方便,同时也没有第二种方法的效率,可谓集百害于一体,所以我就没有这么建议。(噢,当然,还有一种办法就是调整参数的顺序,或者添加一个没有意义的valuetype参数,使得通过参数的位置和排列就能够明显的确定调用的版本是哪一个了。这个方法同样不是很好,因为可能让你的程序看起来不是那么优雅。)

为了检验一下你是否明白了整个规则,我给出另外一个例子。这个例子仍然假设有object、Label、ToolBar三个版本:

Control c = new Label();
Test(c, ...);

答案还是调用了object版本。

为什么我会提出来这个问题呢?因为最近我就遇到了这种情况。在我的程序里面使用的是一个delegate和一个object的版本,我这里用伪代码写一下:

delegate object MyInvoker();

object Test(MyInvoker Invoker,  int Key)
{
  if (HashTable.Contains(Key))
    return HashTable[Key];
  else
  {
    object Result = Invoker();
    HashTable.Add(Key, Result);
    return Result;
  }
}


void Test(object DefaultValue, int Key)
{
  if (HashTable.Contains(Key))
   
return HashTable[Key];
 
else
  {
    HashTable.Add(Key, DefaultValue);
   
return DefaultValue;
  }

}

Test(null, 1);

很明显,我这里是为了缓冲某个数据——如果某个Key所对应的数据不存在,那么要么通过Invoker来返回一个新的实力,要么通过DefaultValue来设置。如果我调用Test(null, 1),那么应该表示如果找不到的话,就设置成null,而不是调用Invoker=null——这明显是非法的,并且没有意义。最后权衡了一下,我还是不用重载的方式,换了一个名字算了。

至于说提出这个问题还有别的原因的,因为有的时候不是编译错误那么简单。比如上面那个例子就是运行时的问题,并且如果这里不是delegate的问题,而是其它类型,那么可能在调用的时候并不知道调用了错误的版本,而等到很后来才出现问题,这时候要找出这个隐含的bug就不是那么简单了。因此我的结论就是,重载的时候需要考虑一下null的问题,并审慎对待重载。
内容概要:该论文聚焦于T2WI核磁共振图像超分辨率问题,提出了一种利用T1WI模态作为辅助信息的跨模态解决方案。其主要贡献包括:提出基于高频信息约束的网络框架,通过主干特征提取分支和高频结构先验建模分支结合Transformer模块和注意力机制有效重建高频细节;设计渐进式特征匹配融合框架,采用多阶段相似特征匹配算法提高匹配鲁棒性;引入模型量化技术降低推理资源需求。实验结果表明,该方法不仅提高了超分辨率性能,还保持了图像质量。 适合人群:从事医学图像处理、计算机视觉领域的研究人员和工程师,尤其是对核磁共振图像超分辨率感兴趣的学者和技术开发者。 使用场景及目标:①适用于需要提升T2WI核磁共振图像分辨率的应用场景;②目标是通过跨模态信息融合提高图像质量,解决传统单模态方法难以克服的高频细节丢失问题;③为临床诊断提供更高质量的影像资料,帮助医生更准确地识别病灶。 其他说明:论文不仅提供了详细的网络架构设计与实现代码,还深入探讨了跨模态噪声的本质、高频信息约束的实现方式以及渐进式特征匹配的具体过程。此外,作者还对模型进行了量化处理,使得该方法可以在资源受限环境下高效运行。阅读时应重点关注论文中提到的技术创新点及其背后的原理,理解如何通过跨模态信息融合提升图像重建效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值