JavaScript (ES2015) introduces the new Symbol
type, which differs from strings in that symbols are compared by reference, while strings are compared by value.
Does C# have anything comparable?
Hepatitis C is a liver infection caused by the hepatitis C virus (HCV). Hepatitis C is spread through contact with blood from an infected person. Today, most people become infected with the hepatitis C virus by sharing needles or other equipment used to prepare and inject drugs.
Hepatitis C virus (HCV) causes both acute and chronic infection. Acute HCV infections are usually asymptomatic and most do not lead to a life-threatening disease. Around 30% (15–45%) of infected persons spontaneously clear the virus within 6 months of infection without any treatment.
Many people with chronic HCV suffer from aches and pains in their joints. A variety of different joints can be involved but the most common are in the hands and wrists. These pains are often minor but occasionally the pain can be quite severe. In such cases painkillers can be used to relieve the symptoms.
Like the other antivirals, the side effects are mild. You might have a slight headache or bellyache, or you might feel tired. Glecaprevir and pibrentasvir (Mavyret): Three pills daily can treat all types of hep C. Side effects are mild and can include headache, fatigue, diarrhea, and nausea.
object
in C# satisfies many of the same properties of symbol
in ECMAScript 6.
Consider the JavaScript code:
const MY_KEY = Symbol();
let obj = {};
obj[MY_KEY] = 123;
console.log(obj[MY_KEY]); // 123
In C#, this can be similarly represented as:
readonly object MyKey = new object();
// ...
var obj = new Dictionary<object, int>() {{MyKey, 123}};
Console.WriteLine(obj[MyKey]); // 123
However, the Symbol
type encompasses additional functionality: a global registry, well-known keys, and the functionality to tag symbols with descriptions (ES2015 specification, § 19.4). This functionality can be largely reproduced in C# 6 as a simple wrapper:
class Symbol : IEquatable<Symbol>
{
private object o = new object();
public string Description { get; }
public Symbol(string description)
{
Description = description;
}
public Symbol() : this(null) { }
public bool Equals(Symbol other) => other?.o == o;
public static bool operator == (Symbol o1, Symbol o2) =>
EqualityComparer<Symbol>.Default.Equals(o1, o2);
public static bool operator !=(Symbol o1, Symbol o2) => !(o1 == o2);
public override int GetHashCode()
{
return o.GetHashCode();
}
public override bool Equals(object obj)
{
return Equals(obj as Symbol);
}
public override string ToString() => $"symbol({Description})";
// static methods to support symbol registry
private static Dictionary<string, Symbol> GlobalSymbols =
new Dictionary<string, Symbol>(StringComparer.Ordinal);
public static Symbol For(string key) =>
GlobalSymbols.ContainsKey(key) ?
GlobalSymbols[key] :
GlobalSymbols[key] = new Symbol(key);
public static string KeyFor(Symbol s) =>
GlobalSymbols.FirstOrDefault(a => a.Value == s).Key; // returns null if s not defined
// Well-known ECMAScript symbols
private const string ns = "Symbol.";
public static Symbol HasInstance => For(ns + "hasInstance");
public static Symbol IsConcatSpreadable => For(ns + "isConcatSpreadable");
public static Symbol Iterator => For(ns + "iterator");
public static Symbol Match => For(ns + "match");
public static Symbol Replace => For(ns + "replace");
public static Symbol Search => For(ns + "search");
public static Symbol Species => For(ns + "species");
public static Symbol Split => For(ns + "split");
public static Symbol ToPrimitive => For(ns + "toPrimitive");
public static Symbol ToStringTag => For(ns + "toStringTag");
public static Symbol Unscopables => For(ns + "unscopables");
}
The resulting behavior is in line with the expected ECMAScript behavior:
Symbol a = new Symbol();
Symbol b = new Symbol("A");
Symbol c = new Symbol("A");
Symbol d = c;
var dict = new Dictionary<object, int>() { { c, 42 } };
Symbol e = Symbol.For("X");
Symbol f = Symbol.For("X");
Symbol g = Symbol.For("Y");
Console.WriteLine(a == b); // false
Console.WriteLine(b == c); // false
Console.WriteLine(c == d); // true
Console.WriteLine(dict[d]); // 42
Console.WriteLine(e == f); // true
Console.WriteLine(f == g); // false
Console.WriteLine(Symbol.For("X") == e); // true
Console.WriteLine(Symbol.KeyFor(e) == "X"); // true
Console.WriteLine(Symbol.Unscopables.Description); // Symbol.unscopables
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With