width = jToken.Value<double?>("width") ?? 100;
from : https://stackoverflow.com/questions/9589218/get-value-from-jtoken-that-may-not-exist-best-practices
width = jToken.Value<double?>("width") ?? 100;

There are only two hard things in Computer Science: cache invalidation and naming things.Phil Karlton
int d; // days until deadline
int daysUntilDealine;
Hungarian notation is an identifier naming convention in computer programming, in which the name of a variable or function indicates its type or intended use.
iStudentAge or intStudentAge. Similarly, a string variable supposed to store a product’s description would be called sProductDescription, or even strProductDescription.productName, would you think it’s a floating-point number? Besides, most modern IDEs can tell you not only the variable’s type, but also if it’s a local variable,instance member or a method parameter, and even how many times it’s been referenced.productName. In Ruby, for instance, the recommended style is snake_case, as in product_name.PrintReport(), DrawShape(IShape shape).Product, Customer, Student. Avoid using the words like Manager, Data, because they add little or no value.Can, Is or Has, when doing so provides value to the caller.The hardest thing about choosing good names is that it requires good descriptive skills and a shared cultural background. This is a teaching issue rather than a technical, business, or management issue. As a result, many people in this field do not do it very well.
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static class CommonExtensions
{
/// <summary>
/// 深層複製(複製對象須可序列化)
/// </summary>
/// <typeparam name="T">複製對象類別</typeparam>
/// <param name="source">複製對象</param>
/// <returns>複製品</returns>
public static T DeepClone<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
if (source != null)
{
using (MemoryStream stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
T clonedSource = (T)formatter.Deserialize(stream);
return clonedSource;
}
}
else
{ return default(T); }
}
}
using Newtonsoft.Json;
public static class CommonExtensions
{
/// <summary>
/// 深層複製(需使用Json.Net組件)
/// </summary>
/// <typeparam name="T">複製對象類別</typeparam>
/// <param name="source">複製對象</param>
/// <returns>複製品</returns>
public static T DeepCloneViaJson<T>(this T source)
{
if (source != null)
{
// avoid self reference loop issue
// track object references when serializing and deserializing JSON
var jsonSerializerSettings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Auto
};
var serializedObj = JsonConvert.SerializeObject(source, Formatting.Indented, jsonSerializerSettings);
return JsonConvert.DeserializeObject<T>(serializedObj, jsonSerializerSettings);
}
else
{ return default(T); }
}
}
public class Utility
{
// Fields
private static List<SelectItem> _notifySelections;
// Properties
public static List<SelectItem> NotifySelections
{
get
{
if (_notifySelections == null)
{
_notifySelections = new List<SelectItem>
{
new SelectItem() { Name="Mail User", Value=1},
new SelectItem() { Name="Call User", Value=2}
};
}
return _notifySelections;
}
}
}
[Serializable]
public class SelectItem
{
public string Name { get; set; }
public int Value { get; set; }
public override string ToString()
{
return string.Format("name:{0} weight:{1}", Name, Value);
}
}

class Program
{
static void Main(string[] args)
{
// show cached NotifySelections
Console.WriteLine("== Utility.NotifySelections ==");
Console.WriteLine(GetContent(Utility.NotifySelections));
// get selections as template
var selections = Utility.NotifySelections;
// replace some info
foreach (var select in selections)
{ select.Name = select.Name.Replace("User", "Chris"); }
// use it as drop down list items
Console.WriteLine("== selections ==");
Console.WriteLine(GetContent(selections));
// show cached NotifySelections
Console.WriteLine("== Utility.NotifySelections ==");
Console.WriteLine(GetContent(Utility.NotifySelections));
}
// show items info
static string GetContent<T>(List<T> items)
{
StringBuilder sb = new StringBuilder();
foreach (var item in items)
{ sb.AppendLine(item.ToString()); }
return sb.ToString();
}
}


_notifySelections.DeepClone() 或 _notifySelections.DeepCloneViaJson()
