Is there a better alternative than this to 'switch on type'?

后端 未结 30 2539
梦毁少年i
梦毁少年i 2020-11-22 03:28

Seeing as C# can\'t switch on a Type (which I gather wasn\'t added as a special case because is relationships mean that more than one distinct

30条回答
  •  死守一世寂寞
    2020-11-22 04:13

    With JaredPar's answer in the back of my head, I wrote a variant of his TypeSwitch class that uses type inference for a nicer syntax:

    class A { string Name { get; } }
    class B : A { string LongName { get; } }
    class C : A { string FullName { get; } }
    class X { public string ToString(IFormatProvider provider); }
    class Y { public string GetIdentifier(); }
    
    public string GetName(object value)
    {
        string name = null;
        TypeSwitch.On(value)
            .Case((C x) => name = x.FullName)
            .Case((B x) => name = x.LongName)
            .Case((A x) => name = x.Name)
            .Case((X x) => name = x.ToString(CultureInfo.CurrentCulture))
            .Case((Y x) => name = x.GetIdentifier())
            .Default((x) => name = x.ToString());
        return name;
    }
    

    Note that the order of the Case() methods is important.


    Get the full and commented code for my TypeSwitch class. This is a working abbreviated version:

    public static class TypeSwitch
    {
        public static Switch On(TSource value)
        {
            return new Switch(value);
        }
    
        public sealed class Switch
        {
            private readonly TSource value;
            private bool handled = false;
    
            internal Switch(TSource value)
            {
                this.value = value;
            }
    
            public Switch Case(Action action)
                where TTarget : TSource
            {
                if (!this.handled && this.value is TTarget)
                {
                    action((TTarget) this.value);
                    this.handled = true;
                }
                return this;
            }
    
            public void Default(Action action)
            {
                if (!this.handled)
                    action(this.value);
            }
        }
    }
    

提交回复
热议问题