C#中宏定义使用“Conditional”和“#if....#endif”的区别

最近在项目中碰到用“[Conditional("xxx")]"来设置方法的执行条件,发现跟原来的"#if....#endif"有些类似,于是查了下两者之间的区别:

Conditional:对于使用“[Conditional("xxx")]”定义的方法而言,该方法是否被执行取决于该方法的调用方是否满足“xxx”环境,如果满足则会执行该方法,否则不执行

#if...#endif:使用这种方式定义的,在编译时只会把满足条件的代码编译到最终的程序集中,与外部调用方是否满足条件无关

现测试如下:

1.使用VS Studio新建一个类库项目,编写如下代码:

using System;
using System.Diagnostics;

namespace CSharpLibraryWithConditional
{
    public class ConditionalClass
    {
        //使用“Conditional"宏定义的方法
        [Conditional("ENABLE_DEBUG")]
        public static void ConditionalMethod()
        {
            Console.WriteLine("This is Conditional-called method.");
        }

        //普通方法
        public static void CommonMethod()
        {
            Console.WriteLine("This is a common method from CSharpLibraryWithConditional.");
        }

        //使用if.....endif宏定义的方法
        public static void IfMethod()
        {
#if DEBUG_IF
            Console.WriteLine("has DEBUG_IF");
#else
            Console.WriteLine("no DEBUG_IF");
#endif
        }
    }
}

此时需要设定宏:在解决方案管理器中选中该工程,右键属性 ——》生成 ——》条件编译和符号,如下所示:

 

设置完毕后,点击生成解决方案(如果已经生成解决方案则点击“重新生成解决方案”):

 在下方的日志中找到生成的dll文件路径:

 在Windows资源管理器中找到该dll文件:

2.将该dll导入到Unity中进行测试:

在Assets下新建“Plugins”文件夹,把该dll放到该路径下:

新建脚本调用该dll中的方法:

public class NewBehaviourScript : MonoBehaviour
{
    void Start()
    {
        Console.SetOut(new UnityTextWriter());   //为了可以在Unity控制台中看到C# dll中的日志输出

        ConditionalClass.ConditionalMethod();    //调用使用“Conditional”定义的
        ConditionalClass.CommonMethod();         //调用普通方法
        ConditionalClass.IfMethod();             //调用使用“#if...#endif”定义的
    }
}

 PS:关于在Unity控制台中显示C# dll中Console.WriteLine日志输出可以查看另一篇:

https://blog.csdn.net/m0_47975736/article/details/120102005?spm=1001.2014.3001.5501

 运行效果如下:

1.当没有在Unity中设置“ENABLE_DEBUG”宏时,效果:

2.当在Unity的“PlayerSetting ->Other Settings"中添加“ENABLE_DEBUG”宏定义时

 

效果如下:

3.为了验证C# dll中本身的宏定义的影响,这里将dll的“ENABLE_DEBUG”宏删除,

重新生成解决方案,并把新生成的dll放到Unity中,重复1,2两步,结果一致

 从以上测试结果可以看出:使用“Conditional”设定的方法其执行取决于调用方是否满足该宏定义的条件,如果满足则执行该方法,否则不执行

 4.对于“#if....#endif”,由于以上类库的宏定义中始终没有“DEBUG_IF",因此生成的程序集中只包含“#else.....#endif"的部分,不论是否在Unity中设定“DEBUG_IF”宏,都不会执行“#if....”的代码

然而当在类库中添加该“DEBUG_IF"宏时,

 重新生成解决方案,把新生成的dll导入到Unity中,经测试可知:

不论是否在Unity中设定“DEBUG_IF”宏,输出结果都是

由此可见:使用"#if.....#endif"只在本程序集内部起到作用,与外部调用方是否包含该宏定义无关

 

其他:

如果需要在同一个方法设定多个“Conditional",可以使用如下形式:

        [Conditional("A"), Conditional("B")]
        public static void Method()
        {

        }

注意:”Conditional("A")", "Conditonal("B")"之间是“or"的关系,如果需要"and"的逻辑关系,则需要这样:

        [Conditional("A")]
        public static void MethodA()
        {
            MethodB();
        }

        [Conditional("B")]
        public static void MethodB()
        {

        }

对于“#if.....#endif"则可以如下方式:

        public static void Method()
        {
#if A && B
            Console.WriteLine("A && B  11111111111");
#else
            Console.WriteLine("no A && B  22222222222");
#endif
        }

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值