Calendar
Mo | Tu | We | Th | Fr | Sa | Su |
---|
30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Archive
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2019
- 2020
|
Website may be up and down over next few months. I'm currently doing a complete overhaul of everything.
Going back to simple individual .htm pages, new overall site theme, sanitizing and cleaning up html of all
pages and blog posts, attempting to implement a new tooling and publishing system etc etc.
Full repo available at https://bitbucket.org/createdbyx/codefarts.utilities-extension-methods-only /// <summary>
/// Inserts a source array into the three dimensional sequence.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array whose value is to be retrieves.</param>
/// <param name="width">The width of the three dimensional sequence.</param>
/// <param name="height">The height of the three dimensional sequence.</param>
/// <param name="destinationArray">The destination array.</param>
/// <param name="depth">The depth of the three dimensional sequence where insertion takes place.</param>
/// <param name="sourceArray">The source array to be inserted.</param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException">
/// width or height is less then 1. Or depth is less then 0.
/// </exception>
/// <exception cref="ArgumentException">'sourceArray' must not be larger then '(width * height)'.</exception>
/// <remarks>The length of the 'sourceArray' parameter cannot be larger then '(width * height)' otherwise the data it contains would overwrite any data
/// stored at a deeper depth.</remarks>
/// <returns>Returns the updated 'destinationArray'.</returns>
public static T[] Insert3D<T>(this T[] destinationArray, int width, int height, int depth, T[] sourceArray)
{
if (width < 1)
{
throw new ArgumentOutOfRangeException("width");
}
if (height < 1)
{
throw new ArgumentOutOfRangeException("height");
}
if (depth < 0)
{
throw new ArgumentOutOfRangeException("depth");
}
if (sourceArray == null || sourceArray.Length == 0)
{
return destinationArray;
}
// ensure source array is no greater then width * height
if (sourceArray.Length > (width * height))
{
throw new ArgumentException("'sourceArray' must not be larger then '(width * height)'", "sourceArray");
}
if (sourceArray.Length < (width * height))
{
Array.Resize(ref sourceArray, width * height);
}
destinationArray = destinationArray.Insert(depth * (width * height), sourceArray);
// return the updated array
return destinationArray;
}
40f258df-f55d-4beb-9ad0-ff43046c6a96|0|.0
Full repo available at https://bitbucket.org/createdbyx/codefarts.utilities-extension-methods-only /// <summary>
/// Sets the depth of the three dimensional sequence.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array whose value is to be retrieves.</param>
/// <param name="width">The width of the three dimensional sequence.</param>
/// <param name="height">The height of the three dimensional sequence.</param>
/// <param name="value">The new depth of the three dimensional sequence.</param>
/// <exception cref="ArgumentOutOfRangeException">
/// width or height is less then 1.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">'value' must be greater then 0.</exception>
public static T[] Set3DDepth<T>(this T[] array, int width, int height, int value)
{
if (width < 1)
{
throw new ArgumentOutOfRangeException("width");
}
if (height < 1)
{
throw new ArgumentOutOfRangeException("height");
}
if (value < 1)
{
throw new ArgumentOutOfRangeException("value");
}
// resize the array preserving contents
Array.Resize(ref array, value * (width * height));
return array;
}
85801e47-87c6-4693-8c69-14020c5dca67|0|.0
Full repo available at https://bitbucket.org/createdbyx/codefarts.utilities-extension-methods-only /// <summary>
/// Gets the value in a single dimensional array that represents a three dimensional sequence.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array whose value is to be retrieves.</param>
/// <param name="width">The width of the three dimensional sequence.</param>
/// <param name="height">The height of the three dimensional sequence.</param>
/// <param name="x">The x index (0 to width - 1).</param>
/// <param name="y">The y index (0 to height - 1).</param>
/// <param name="z">The z index (0 to depth - 1).</param>
/// <returns>Returns the value stored in the array.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// width or height is less then 1.
/// </exception>
/// <remarks>
/// <p>This method provides an alternative to working with three dimensional arrays "var value = new int[3,3,3];" by operating
/// on a single dimensional array using a math formula to determine the index into the array.</p>
/// <p>Think of a multi-layered image. Each image layer consists of a grid of cells defined by width * height.</p>
/// <p>We can use the formula "layer * (width * height)" to get the starting index of the layer in the array.
/// To get the index in the image we can use the formula "(y * width) + x".
/// Combining these two formulas we can access any grid cell of any layer in the array like so "(layer * (width * height)) + ((y * width) + x)".</p>
/// <p>This method does not perform range checking and will throw index out of range exceptions if invalid arguments are specified.</p></remarks>
public static T Get3D<T>(this T[] array, int width, int height, int x, int y, int z)
{
if (width < 1)
{
throw new ArgumentOutOfRangeException("width");
}
if (height < 1)
{
throw new ArgumentOutOfRangeException("height");
}
return array[(z * (width * height)) + ((y * width) + x)];
}
7b65b1d4-739b-4c53-ad2c-4c3da8360a7c|0|.0
Full repo available at https://bitbucket.org/createdbyx/codefarts.utilities-extension-methods-only
/// <summary>
/// Sets the value in a single dimensional array that represents a three dimensional sequence.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array whose value is to be set.</param>
/// <param name="width">The width of the three dimensional sequence.</param>
/// <param name="height">The height of the three dimensional sequence.</param>
/// <param name="x">The x index (0 to width - 1).</param>
/// <param name="y">The y index (0 to height - 1).</param>
/// <param name="z">The z index (0 to depth - 1).</param>
/// <param name="value">The value to set.</param>
/// <exception cref="ArgumentOutOfRangeException">
/// width or height is less then 1.
/// </exception>
/// <remarks>
/// <p>This method provides an alternative to working with three dimensional arrays "var value = new int[3,3,3];" by operating
/// on a single dimensional array using a math formula to determine the index into the array.</p>
/// <p>Think of a multi-layered image. Each image layer consists of a grid of cells defined by width * height.</p>
/// <p>We can use the formula "layer * (width * height)" to get the starting index of the layer in the array.
/// To get the index in the image we can use the formula "(y * width) + x".
/// Combining these two formulas we can access any grid cell of any layer in the array like so "(layer * (width * height)) + ((y * width) + x)".</p>
/// <p>This method does not perform range checking and will throw index out of range exceptions if invalid arguments are specified.</p>
/// </remarks>
public static void Set3D<T>(this T[] array, int width, int height, int x, int y, int z, T value)
{
if (width < 1)
{
throw new ArgumentOutOfRangeException("width");
}
if (height < 1)
{
throw new ArgumentOutOfRangeException("height");
}
array[(z * (width * height)) + ((y * width) + x)] = value;
}
6e2ec132-aa6e-4b65-9c7a-0e7cdaf166bc|0|.0
If you are writing custom scripts there may be situations where you don’t want the same component added more then once to a game object. For such situations Unity provides the DisallowMultipleComponent attribute that you can specify in your scripts code.
b9d4fae6-2759-417d-8fd3-abf86cb2fc3e|0|.0
The fallowing script allows you to control fog settings on a per camera basis, allowing you to use say green fog for one camera but red fog for another camera.
Unity 5 package demo is available here CameraFog.unitypackage (46.66 kb)
CameraFog.cs script
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CameraFog.cs" company="Codefarts">
// Copyright (c) 2012 Codefarts
// All rights reserved.
// contact@codefarts.com
// http://www.codefarts.com
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
// Per-camera fog
// This is a simple class that, when added to a GameObject with a camera, allows you to control the fog settings for that camera separately from the global ones.
// I'd love to hear from you if you do anything cool with this or have any suggestions :)
// Original author: http://wiki.unity3d.com/index.php/User:Tenebrous
// Author website as of 2015: www.tenebrous.co.uk
// Source: http://wiki.unity3d.com/index.php/CameraFog
namespace Codefarts.GeneralTools.Scripts.Camera
{
using UnityEngine;
/// <summary>
/// Modifies a camera to allows you to control the fog settings for that camera separately from the global scene fog or other cameras.
/// </summary>
[RequireComponent(typeof(Camera))]
[ExecuteInEditMode]
public class CameraFog : MonoBehaviour
{
/// <summary>
/// The enabled state weather or not fog will be visible.
/// </summary>
public bool Enabled;
/// <summary>
/// The start distance from the camera where the fog will be drawn.
/// </summary>
public float StartDistance;
/// <summary>
/// The end distance from the camera where the fog will be drawn.
/// </summary>
public float EndDistance;
/// <summary>
/// The fog mode that controls how the fog is rendered.
/// </summary>
public FogMode Mode;
/// <summary>
/// The density of the fog that is rendered.
/// </summary>
public float Density;
/// <summary>
/// The fog color.
/// </summary>
public Color Color;
/// <summary>
/// Stores the pre-render state of the start distance.
/// </summary>
private float _startDistance;
/// <summary>
/// Stores the pre-render state of the end distance.
/// </summary>
private float _endDistance;
/// <summary>
/// Stores the pre-render state of the fog mode.
/// </summary>
private FogMode _mode;
/// <summary>
/// Stores the pre-render state of the density.
/// </summary>
private float _density;
/// <summary>
/// Stores the pre-render state of the fog color.
/// </summary>
private Color _color;
/// <summary>
/// Stores the pre-render state wheather or not the fog is enabled.
/// </summary>
private bool _enabled;
/// <summary>
/// Event that is fired before any camera starts rendering.
/// </summary>
private void OnPreRender()
{
this._startDistance = RenderSettings.fogStartDistance;
this._endDistance = RenderSettings.fogEndDistance;
this._mode = RenderSettings.fogMode;
this._density = RenderSettings.fogDensity;
this._color = RenderSettings.fogColor;
this._enabled = RenderSettings.fog;
RenderSettings.fog = this.Enabled;
RenderSettings.fogStartDistance = this.StartDistance;
RenderSettings.fogEndDistance = this.EndDistance;
RenderSettings.fogMode = this.Mode;
RenderSettings.fogDensity = this.Density;
RenderSettings.fogColor = this.Color;
}
/// <summary>
/// Event that is fired after any camera finishes rendering.
/// </summary>
private void OnPostRender()
{
RenderSettings.fog = this._enabled;
RenderSettings.fogStartDistance = this._startDistance;
RenderSettings.fogEndDistance = this._endDistance;
RenderSettings.fogMode = this._mode;
RenderSettings.fogDensity = this._density;
RenderSettings.fogColor = this._color;
}
}
}
3e68139e-e598-4f81-95a0-97e5ff0eeec9|0|.0
With the introduction to Unity 5 there comes some api changes. Specifically this foot note was interesting “[2] in Unity5 we also cache the transform component on the c# side, so there should no longer be a performance reason to cache the transform component yourself.”
I decided to test it out by writing a few performance test scripts and comparing performance numbers. Below is a screen shot of my results along with the scripts used.
As you can see caching a reference to the transform component in the Start method then using that reference is still faster then calling “this.transform” directly albeit only slightly by about 10-20 ticks. And calling “this.GetComponent<Transform>()” is almost twice as slow.
The code for the PerformanceTesting class is availible here.
TransformCachedGetComponentPerformance script
using UnityEngine;
public class TransformCachedGetComponentPerformance : MonoBehaviour
{
private Transform reference;
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
public void Awake()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Create("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
}
/// <summary>
/// Start is called just before any of the Update methods is called the first time.
/// </summary>
public void Start()
{
this.reference = this.GetComponent<Transform>();
}
/// <summary>
/// Update is called every frame, if the MonoBehaviour is enabled.
/// </summary>
public void Update()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Start("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
var rnd = new System.Random();
this.reference.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
#if PERFORMANCE
perf.Stop("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
}
}
TransformGetComponentPerformance script
using UnityEngine;
public class TransformGetComponentPerformance : MonoBehaviour
{
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
public void Awake()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Create("UnityTesting/TransformGetComponentPerformance/Update");
#endif
}
/// <summary>
/// Update is called every frame, if the MonoBehaviour is enabled.
/// </summary>
public void Update()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Start("UnityTesting/TransformGetComponentPerformance/Update");
#endif
var rnd = new System.Random();
this.GetComponent<Transform>().localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
#if PERFORMANCE
perf.Stop("UnityTesting/TransformGetComponentPerformance/Update");
#endif
}
}
TransformFieldPerformance script
using UnityEngine;
public class TransformFieldPerformance : MonoBehaviour
{
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
public void Awake()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Create("UnityTesting/TransformFieldPerformance/Update");
#endif
}
/// <summary>
/// Update is called every frame, if the MonoBehaviour is enabled.
/// </summary>
public void Update()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Start("UnityTesting/TransformFieldPerformance/Update");
#endif
var rnd = new System.Random();
this.transform.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
#if PERFORMANCE
perf.Stop("UnityTesting/TransformFieldPerformance/Update");
#endif
}
}
0631a2dd-08a4-4b60-b9fa-0f8221b4adb9|2|5.0
The fallowing code snip is designed to take in a flat list of file paths (or similar data) and produce a hierarchy of tree nodes representing those file paths.
/// <summary>
/// Constructs a nested hierarchy of types from a flat list of source types.
/// </summary>
/// <typeparam name="TSource">The source type of the flat list that is to be converted.</typeparam>
/// <typeparam name="TReturn">The type that will be returned.</typeparam>
/// <typeparam name="TPart">The type of the art type.</typeparam>
/// <param name="sourceItems">The source items to be converted.</param>
/// <param name="getParts">A callback function that returns a array of <see cref="TPart"/>.</param>
/// <param name="comparePart">The compare part callback.</param>
/// <param name="getChildren">The get children callback.</param>
/// <param name="addChild">The add child callback.</param>
/// <param name="createItem">The create item callback.</param>
/// <returns>Returns an collection of <see cref="TReturn"/> representing the hierarchy.</returns>
/// <exception cref="Exception">A delegate callback throws an exception. </exception>
private static IEnumerable<TReturn> ToHierarchy<TSource, TReturn, TPart>(
IEnumerable<TSource> sourceItems,
Func<TSource, TPart[]> getParts,
Func<TReturn, TPart, bool> comparePart,
Func<TReturn, IEnumerable<TReturn>> getChildren,
Action<IEnumerable<TReturn>, TReturn> addChild,
Func<TPart[], int, TSource, TReturn> createItem)
{
var treeModels = new List<TReturn>();
foreach (var keyName in sourceItems)
{
IEnumerable<TReturn> items = treeModels;
var parts = getParts(keyName);
for (var partIndex = 0; partIndex < parts.Length; partIndex++)
{
var node = items.FirstOrDefault(x => comparePart(x, parts[partIndex]));
if (node != null)
{
items = getChildren(node);
continue;
}
var model = createItem(parts, partIndex, keyName);
addChild(items, model);
items = getChildren(model);
}
}
return treeModels;
}
An example of how one could use the ToHierarchy method would be like this …
var separator = new[] { Path.AltDirectorySeparatorChar.ToString(CultureInfo.InvariantCulture) };
// paths varible could be something from Directory.GetDirectories method for example.
var nodes = ToHierarchy<string, TreeViewNode, string>(
paths.OrderBy(x => x),
x => x.Split(separator, StringSplitOptions.RemoveEmptyEntries),
(r, p) => string.CompareOrdinal(r.Name, p) == 0,
r => r.Nodes,
(r, c) => ((List<TreeViewNode>)r).Add(c),
this.CreateTreeNode);
private TreeViewNode CreateTreeNode(string[] parts, int index, string source)
{
var node = new TreeViewNode() { Name = parts[index] };
node.Value = string.Join(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), parts, 0, index + 1);
if (index == parts.Length - 1)
{
node.Name = Path.GetFileName(source);
}
node.IsFile = File.Exists(node.Value);
return node;
}
Where paths is a array of file paths from say Directory.GetFiles.
3bebbb17-378e-4ffb-b2dd-e42a8fb57745|0|.0
Source: http://stackoverflow.com/questions/616718/how-do-i-get-common-file-type-icons-in-c public static class FileIcon
{
[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
private const uint SHGFI_ICON = 0x100;
private const uint SHGFI_LARGEICON = 0x0; // 'Large icon
private const uint SHGFI_SMALLICON = 0x1; // 'Small icon
public static System.Drawing.Icon GetLargeIcon(string file)
{
var shinfo = new SHFILEINFO();
var hImgLarge = SHGetFileInfo(file, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), FileIcon.SHGFI_ICON | FileIcon.SHGFI_LARGEICON);
return System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
public static System.Drawing.Icon GetSmallIcon(string file)
{
var shinfo = new SHFILEINFO();
var hImgLarge = SHGetFileInfo(file, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), FileIcon.SHGFI_ICON | FileIcon.SHGFI_SMALLICON);
return System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
}
22617284-c3d3-4a4f-8daf-00924d264f58|0|.0
// <copyright>
// Copyright (c) 2012 Codefarts
// All rights reserved.
// contact@codefarts.com
// http://www.codefarts.com
// </copyright>
namespace Codefarts.ObjectPooling
{
using System;
/// <summary>
/// Provides a generic object pooling manager.
/// </summary>
/// <typeparam name="T"></typeparam>
public class ObjectPoolManager<T> where T : class
{
/// <summary>
/// Holds a reference to a singleton instance.
/// </summary>
private static ObjectPoolManager<T> instance;
/// <summary>
/// Used to track the number of items that have been pushed to the pool.
/// </summary>
private int count;
/// <summary>
/// Holds the pooled item references.
/// </summary>
private T[] cachedItems = new T[10000];
/// <summary>
/// Gets or sets the creation callback.
/// </summary>
public Func<T> CreationCallback { get; set; }
/// <summary>
/// Gets the number of items in the pool.
/// </summary>
public int Count
{
get
{
return this.count;
}
}
/// <summary>
/// Pops a item from the pool.
/// </summary>
/// <returns>A pooled object reference.</returns>
/// <exception cref="System.NullReferenceException">'CreationCallback' property must be set if you try to pop a item and there are no items available.</exception>
public T Pop()
{
// lock here to prevent treading conflicts with array manipulation
lock (this.cachedItems)
{
// check if there are any pooled objects
if (this.count < 1)
{
// check if creation callback is null
if (this.CreationCallback == null)
{
throw new NullReferenceException("'CreationCallback' property must be set if you try to pop a item and there are no items available.");
}
// there are no available objects so create a new one.
return this.CreationCallback();
}
// reduce the count
this.count--;
// retrieve the item and return it
return this.cachedItems[this.count];
}
}
/// <summary>
/// Pushes the specified value.
/// </summary>
/// <param name="value">The value to push into the pool.</param>
public void Push(T value)
{
// lock here to prevent treading conflicts with array manipulation
lock (this.cachedItems)
{
// update the count
this.count++;
// if we need more room for storage increase the size of the cache array
if (this.count > this.cachedItems.Length)
{
Array.Resize(ref this.cachedItems, this.cachedItems.Length * 2);
}
// store the value
this.cachedItems[this.count - 1] = value;
}
}
/// <summary>
/// Gets the singleton instance of the class.
/// </summary>
public static ObjectPoolManager<T> Instance
{
get
{
return instance ?? (instance = new ObjectPoolManager<T>());
}
}
}
}
And some unit tests to go along with it.
// <copyright>
// Copyright (c) 2012 Codefarts
// All rights reserved.
// contact@codefarts.com
// http://www.codefarts.com
// </copyright>
namespace Codefarts.Tests.ObjectPooling
{
using System;
using Codefarts.ObjectPooling;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
[TestClass]
public class ObjectPoolingManagerTests
{
ObjectPoolManager<TestObject> manager;
[TestInitialize]
public void Setup()
{
this.manager = new ObjectPoolManager<TestObject>();
}
[TestCleanup]
public void Cleanup()
{
this.manager = null;
}
public class TestObject
{
public string stringValue;
public int intValue;
}
[TestMethod]
public void Pop_With_Empty_Pool_NoCallback()
{
try
{
var item = this.manager.Pop();
Assert.IsNotNull(item);
}
catch (Exception ex)
{
Assert.IsTrue(ex is NullReferenceException);
}
}
[TestMethod]
public void Pop_With_Empty_Pool_WithCallback()
{
try
{
this.manager.CreationCallback = this.Callback;
var item = this.manager.Pop();
Assert.IsNotNull(item);
Assert.AreEqual(0, item.intValue);
Assert.AreEqual(null, item.stringValue);
}
catch (Exception ex)
{
Assert.IsTrue(ex is NullReferenceException);
}
}
private TestObject Callback()
{
return new TestObject();
}
[TestMethod]
public void Push_Object()
{
try
{
Assert.AreEqual(0, this.manager.Count);
this.manager.Push(new TestObject());
Assert.AreEqual(1, this.manager.Count);
}
catch (Exception ex)
{
Assert.Fail(ex.ToString());
}
}
[TestMethod]
public void Push_Pop_Objects()
{
try
{
Assert.AreEqual(0, this.manager.Count);
for (var i = 0; i < 3; i++)
{
this.manager.Push(new TestObject() { stringValue = "Item" + i, intValue = i });
}
Assert.AreEqual(3, this.manager.Count);
for (var i = 3 - 1; i >= 0; i--)
{
var item = this.manager.Pop();
Assert.AreEqual(i, item.intValue);
Assert.AreEqual("Item" + i, item.stringValue);
}
Assert.AreEqual(0, this.manager.Count);
}
catch (Exception ex)
{
Assert.Fail(ex.ToString());
}
}
}
}
a6075769-d4e3-4634-9ad9-6bd31ae2249f|0|.0
|
|