Verify.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*************************************************************************************
  2. Extended WPF Toolkit
  3. Copyright (C) 2007-2013 Xceed Software Inc.
  4. This program is provided to you under the terms of the Microsoft Public
  5. License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
  6. For more features, controls, and fast professional support,
  7. pick up the Plus Edition at http://xceed.com/wpf_toolkit
  8. Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
  9. ***********************************************************************************/
  10. /**************************************************************************\
  11. Copyright Microsoft Corporation. All Rights Reserved.
  12. \**************************************************************************/
  13. // This file contains general utilities to aid in development.
  14. // Classes here generally shouldn't be exposed publicly since
  15. // they're not particular to any library functionality.
  16. // Because the classes here are internal, it's likely this file
  17. // might be included in multiple assemblies.
  18. namespace Standard
  19. {
  20. using System;
  21. using System.Diagnostics;
  22. using System.Diagnostics.CodeAnalysis;
  23. using System.Globalization;
  24. using System.IO;
  25. using System.Threading;
  26. /// <summary>
  27. /// A static class for retail validated assertions.
  28. /// Instead of breaking into the debugger an exception is thrown.
  29. /// </summary>
  30. internal static class Verify
  31. {
  32. /// <summary>
  33. /// Ensure that the current thread's apartment state is what's expected.
  34. /// </summary>
  35. /// <param name="requiredState">
  36. /// The required apartment state for the current thread.
  37. /// </param>
  38. /// <param name="message">
  39. /// The message string for the exception to be thrown if the state is invalid.
  40. /// </param>
  41. /// <exception cref="InvalidOperationException">
  42. /// Thrown if the calling thread's apartment state is not the same as the requiredState.
  43. /// </exception>
  44. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  45. [DebuggerStepThrough]
  46. public static void IsApartmentState(ApartmentState requiredState, string message)
  47. {
  48. if (Thread.CurrentThread.GetApartmentState() != requiredState)
  49. {
  50. throw new InvalidOperationException(message);
  51. }
  52. }
  53. /// <summary>
  54. /// Ensure that an argument is neither null nor empty.
  55. /// </summary>
  56. /// <param name="value">The string to validate.</param>
  57. /// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
  58. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  59. [SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
  60. [DebuggerStepThrough]
  61. public static void IsNeitherNullNorEmpty(string value, string name)
  62. {
  63. // catch caller errors, mixing up the parameters. Name should never be empty.
  64. Assert.IsNeitherNullNorEmpty(name);
  65. // Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
  66. const string errorMessage = "The parameter can not be either null or empty.";
  67. if (null == value)
  68. {
  69. throw new ArgumentNullException(name, errorMessage);
  70. }
  71. if ("" == value)
  72. {
  73. throw new ArgumentException(errorMessage, name);
  74. }
  75. }
  76. /// <summary>
  77. /// Ensure that an argument is neither null nor does it consist only of whitespace.
  78. /// </summary>
  79. /// <param name="value">The string to validate.</param>
  80. /// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
  81. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  82. [SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
  83. [DebuggerStepThrough]
  84. public static void IsNeitherNullNorWhitespace(string value, string name)
  85. {
  86. // catch caller errors, mixing up the parameters. Name should never be empty.
  87. Assert.IsNeitherNullNorEmpty(name);
  88. // Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
  89. const string errorMessage = "The parameter can not be either null or empty or consist only of white space characters.";
  90. if (null == value)
  91. {
  92. throw new ArgumentNullException(name, errorMessage);
  93. }
  94. if ("" == value.Trim())
  95. {
  96. throw new ArgumentException(errorMessage, name);
  97. }
  98. }
  99. /// <summary>Verifies that an argument is not null.</summary>
  100. /// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
  101. /// <param name="obj">The object to validate.</param>
  102. /// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
  103. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  104. [DebuggerStepThrough]
  105. public static void IsNotDefault<T>(T obj, string name) where T : struct
  106. {
  107. if (default(T).Equals(obj))
  108. {
  109. throw new ArgumentException("The parameter must not be the default value.", name);
  110. }
  111. }
  112. /// <summary>Verifies that an argument is not null.</summary>
  113. /// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
  114. /// <param name="obj">The object to validate.</param>
  115. /// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
  116. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  117. [DebuggerStepThrough]
  118. public static void IsNotNull<T>(T obj, string name) where T : class
  119. {
  120. if (null == obj)
  121. {
  122. throw new ArgumentNullException(name);
  123. }
  124. }
  125. /// <summary>Verifies that an argument is null.</summary>
  126. /// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
  127. /// <param name="obj">The object to validate.</param>
  128. /// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
  129. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  130. [DebuggerStepThrough]
  131. public static void IsNull<T>(T obj, string name) where T : class
  132. {
  133. if (null != obj)
  134. {
  135. throw new ArgumentException("The parameter must be null.", name);
  136. }
  137. }
  138. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  139. [DebuggerStepThrough]
  140. public static void PropertyIsNotNull<T>(T obj, string name) where T : class
  141. {
  142. if (null == obj)
  143. {
  144. throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The property {0} cannot be null at this time.", name));
  145. }
  146. }
  147. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  148. [DebuggerStepThrough]
  149. public static void PropertyIsNull<T>(T obj, string name) where T : class
  150. {
  151. if (null != obj)
  152. {
  153. throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The property {0} must be null at this time.", name));
  154. }
  155. }
  156. /// <summary>
  157. /// Verifies the specified statement is true. Throws an ArgumentException if it's not.
  158. /// </summary>
  159. /// <param name="statement">The statement to be verified as true.</param>
  160. /// <param name="name">Name of the parameter to include in the ArgumentException.</param>
  161. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  162. [DebuggerStepThrough]
  163. public static void IsTrue(bool statement, string name)
  164. {
  165. if (!statement)
  166. {
  167. throw new ArgumentException("", name);
  168. }
  169. }
  170. /// <summary>
  171. /// Verifies the specified statement is true. Throws an ArgumentException if it's not.
  172. /// </summary>
  173. /// <param name="statement">The statement to be verified as true.</param>
  174. /// <param name="name">Name of the parameter to include in the ArgumentException.</param>
  175. /// <param name="message">The message to include in the ArgumentException.</param>
  176. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  177. [DebuggerStepThrough]
  178. public static void IsTrue(bool statement, string name, string message)
  179. {
  180. if (!statement)
  181. {
  182. throw new ArgumentException(message, name);
  183. }
  184. }
  185. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  186. [DebuggerStepThrough]
  187. public static void AreEqual<T>(T expected, T actual, string parameterName, string message)
  188. {
  189. if (null == expected)
  190. {
  191. // Two nulls are considered equal, regardless of type semantics.
  192. if (null != actual && !actual.Equals(expected))
  193. {
  194. throw new ArgumentException(message, parameterName);
  195. }
  196. }
  197. else if (!expected.Equals(actual))
  198. {
  199. throw new ArgumentException(message, parameterName);
  200. }
  201. }
  202. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  203. [DebuggerStepThrough]
  204. public static void AreNotEqual<T>(T notExpected, T actual, string parameterName, string message)
  205. {
  206. if (null == notExpected)
  207. {
  208. // Two nulls are considered equal, regardless of type semantics.
  209. if (null == actual || actual.Equals(notExpected))
  210. {
  211. throw new ArgumentException(message, parameterName);
  212. }
  213. }
  214. else if (notExpected.Equals(actual))
  215. {
  216. throw new ArgumentException(message, parameterName);
  217. }
  218. }
  219. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  220. [DebuggerStepThrough]
  221. public static void UriIsAbsolute(Uri uri, string parameterName)
  222. {
  223. Verify.IsNotNull(uri, parameterName);
  224. if (!uri.IsAbsoluteUri)
  225. {
  226. throw new ArgumentException("The URI must be absolute.", parameterName);
  227. }
  228. }
  229. /// <summary>
  230. /// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
  231. /// </summary>
  232. /// <param name="lowerBoundInclusive">The lower bound inclusive value.</param>
  233. /// <param name="value">The value to verify.</param>
  234. /// <param name="upperBoundExclusive">The upper bound exclusive value.</param>
  235. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  236. [DebuggerStepThrough]
  237. public static void BoundedInteger(int lowerBoundInclusive, int value, int upperBoundExclusive, string parameterName)
  238. {
  239. if (value < lowerBoundInclusive || value >= upperBoundExclusive)
  240. {
  241. throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The integer value must be bounded with [{0}, {1})", lowerBoundInclusive, upperBoundExclusive), parameterName);
  242. }
  243. }
  244. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  245. [DebuggerStepThrough]
  246. public static void BoundedDoubleInc(double lowerBoundInclusive, double value, double upperBoundInclusive, string message, string parameter)
  247. {
  248. if (value < lowerBoundInclusive || value > upperBoundInclusive)
  249. {
  250. throw new ArgumentException(message, parameter);
  251. }
  252. }
  253. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  254. [DebuggerStepThrough]
  255. public static void TypeSupportsInterface(Type type, Type interfaceType, string parameterName)
  256. {
  257. Assert.IsNeitherNullNorEmpty(parameterName);
  258. Verify.IsNotNull(type, "type");
  259. Verify.IsNotNull(interfaceType, "interfaceType");
  260. if (type.GetInterface(interfaceType.Name) == null)
  261. {
  262. throw new ArgumentException("The type of this parameter does not support a required interface", parameterName);
  263. }
  264. }
  265. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  266. [DebuggerStepThrough]
  267. public static void FileExists(string filePath, string parameterName)
  268. {
  269. Verify.IsNeitherNullNorEmpty(filePath, parameterName);
  270. if (!File.Exists(filePath))
  271. {
  272. throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No file exists at \"{0}\"", filePath), parameterName);
  273. }
  274. }
  275. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  276. [DebuggerStepThrough]
  277. internal static void ImplementsInterface(object parameter, Type interfaceType, string parameterName)
  278. {
  279. Assert.IsNotNull(parameter);
  280. Assert.IsNotNull(interfaceType);
  281. Assert.IsTrue(interfaceType.IsInterface);
  282. bool isImplemented = false;
  283. foreach (var ifaceType in parameter.GetType().GetInterfaces())
  284. {
  285. if (ifaceType == interfaceType)
  286. {
  287. isImplemented = true;
  288. break;
  289. }
  290. }
  291. if (!isImplemented)
  292. {
  293. throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString()), parameterName);
  294. }
  295. }
  296. }
  297. }