利用 Conditional 属性,程序员可以定义条件方法。Conditional 属性通过测试条件编译符号来确定适用的条件。当运行到一个条件方法调用时,是否执行该调用,要根据出现该调用时是否已定义了此符号来确定。如果定义了此符号,则执行该调用;否则省略该调用(包括对调用的参数的计算)。
条件方法要受到以下限制:
- 条件方法必须是类声明或结构声明中的方法。如果在接口声明中的方法上指定
Conditional
属性,将出现编译时错误。 - 条件方法必须具有
void
返回类型。 - 不能用
override
修饰符标记条件方法。但是,可以用virtual
修饰符标记条件方法。此类方法的重写方法隐含为有条件的方法,而且不能用Conditional
属性显式标记。 - 条件方法不能是接口方法的实现。否则将发生编译时错误。
- 如果条件方法用在“委托创建表达式”中,也会发生编译时错误
Ps.尽量使用Conditional属性代替#if和#endif
/*MyConditional.cs*/
//#define DEBUG
using System;
using System.Diagnostics;
class Info
{
//[Conditional("DEBUG")]
public static void Trace(string strMessage)
{
Console.WriteLine(strMessage);
}
[Conditional("DEBUG")]
public static void TraceX(string strFormat,params object[] list)
{
Console.WriteLine(strFormat, list);
}
}
class TestConditional
{
public static void Main()
{
Info.Trace("Cool!");
Info.TraceX("{0} {1} {2}","C", "U", 2001);
}
}
/*
编译方式1:
csc /define:DEBUG /out:1.exe MyConditional.cs
运行结果1:
Cool!
C U 2001
*/
/*
编译方式2:
csc /out:1.exe MyConditional.cs
运行结果2:
Cool!
*/
unity中的是用,用来进行日志的输出:
using UnityEngine;
using System.Diagnostics;
using System.Net;
using System;
using Debug = UnityEngine.Debug;
using System.Collections.Generic;
using System.Text;
public class Logger
{
static protected Stopwatch watch = new Stopwatch();
private static WebClient m_webClient = new WebClient();
private static List<string> m_errorList = new List<string>();
private static bool m_canTakeError = true;
private static bool m_isInit = false;
private static int counter = 0;
private static StringBuilder sb = new StringBuilder();
public static string clientVerstion = string.Empty;
public static string loginUid = string.Empty;
public static string localIP = string.Empty;
public static string platName = string.Empty;
public static string sceneName = "Launch";
public static string DEBUG_BUILD_VER = "HOG_ALPHA_1";
public static string platChannel = "outnet";
[Conditional("UNITY_EDITOR")]
[Conditional("LOGGER_ON")]
static public void Log(string s, params object[] p)
{
Debug.Log(DateTime.Now + " -- " + (p != null && p.Length > 0 ? string.Format(s, p) : s));
}
[Conditional("UNITY_EDITOR")]
[Conditional("LOGGER_ON")]
static public void Log(object o)
{
Debug.Log(o);
}
[Conditional("UNITY_EDITOR")]
[Conditional("LOGGER_ON")]
public static void LogToMainThread(string s, params object[] p)
{
string msg = (p != null && p.Length > 0 ? string.Format(s, p) : s);
LoggerHelper.Instance.LogToMainThread(LoggerHelper.LOG_TYPE.LOG, msg);
}
[Conditional("UNITY_EDITOR")]
[Conditional("LOGGER_ON")]
static public void Assert(bool condition, string s, params object[] p)
{
if (condition)
{
return;
}
LogError("Assert failed! Message:\n" + s, p);
}
static public void LogError(string s, params object[] p)
{
#if UNITY_EDITOR || LOGGER_ON
Debug.LogError((p != null && p.Length > 0 ? string.Format(s, p) : s));
#else
AddError(string.Format("clientversion:{0} uid: {1} device:{2} ip:{3} platname:{4} platChannel:{5} scenename:{6} debug_build_ver:{7} \n {8} ",
clientVerstion, loginUid, (SystemInfo.deviceModel + "/" + SystemInfo.deviceUniqueIdentifier), localIP, platName, platChannel, sceneName, DEBUG_BUILD_VER,
(p != null && p.Length > 0 ? string.Format(s, p) : s)));
#endif
}
public static void LogErrorToMainThread(string s, params object[] p)
{
string msg = (p != null && p.Length > 0 ? string.Format(s, p) : s);
LoggerHelper.Instance.LogToMainThread(LoggerHelper.LOG_TYPE.LOG_ERR, msg);
}
static public void LogStackTrace(string str)
{
StackFrame[] stacks = new StackTrace().GetFrames();
string result = str + "\r\n";
if (stacks != null)
{
for (int i = 0; i < stacks.Length; i++)
{
result += string.Format("{0} {1}\r\n", stacks[i].GetFileName(), stacks[i].GetMethod().ToString());
//result += stacks[i].ToString() + "\r\n";
}
}
LogError(result);
}
private static void AddError(string errorStr)
{
if (!string.IsNullOrEmpty(errorStr))
{
m_errorList.Add(errorStr);
}
}
private static void SendToHttpSvr(string postData)
{
if (!string.IsNullOrEmpty(postData))
{
//Logger.Log("error:" + postData);
if (!m_isInit)
{
m_webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(OnUploadStringCompleted);
m_isInit = true;
}
m_webClient.UploadStringAsync(new Uri(URLSetting.REPORT_ERROR_URL), "POST", postData);
}
}
public static void CheckReportError()
{
counter++;
if (counter % 5 == 0 && m_canTakeError)
{
DealWithReportError();
counter = (counter > 1000) ? 0 : counter;
}
}
private static void DealWithReportError()
{
int errorCount = m_errorList.Count;
if (errorCount > 0)
{
m_canTakeError = false;
counter = 0;
sb.Length = 0;
for (int i = 0; i < errorCount; i++)
{
sb.Append(m_errorList[i] + " | \n");
}
m_errorList.Clear();
SendToHttpSvr(sb.ToString());
}
}
static void OnUploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
m_canTakeError = true;
}
[Conditional("UNITY_EDITOR")]
static public void Watch()
{
#if UNITY_EDITOR
watch.Reset();
watch.Start();
#endif
}
static public long useTime
{
get
{
#if UNITY_EDITOR
return watch.ElapsedMilliseconds;
#else
return 0;
#endif
}
}
static public string useMemory
{
get
{
#if UNITY_5_6_OR_NEWER
return (UnityEngine.Profiling.Profiler.usedHeapSizeLong / 1024 / 1024).ToString() + " mb";
#elif UNITY_5_5_OR_NEWER
return (UnityEngine.Profiling.Profiler.usedHeapSize / 1024 / 1024).ToString() + " mb";
#else
return (Profiler.usedHeapSize / 1024 / 1024).ToString() + " mb";
#endif
}
}
}
**
网友评论