Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C# have a symbol type?

Tags:

javascript

c#

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?

like image 650
Golo Roden Avatar asked Dec 19 '15 13:12

Golo Roden


People also ask

What is the main cause of hep C?

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.

Does hep C go away?

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.

What does hep C pain feel like?

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.

Does hep C treatment make you sick?

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.


1 Answers

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
like image 167
drf Avatar answered Oct 14 '22 01:10

drf