最近在项目中碰到用“[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
}