I have function that builds different types of boxes.    namespace TestSome.ViewModel{    public class OneBoxViewModel : ViewModelBase    {        private ObservableCollection<BaseBox> boxes;        public ObservableCollection<BaseBox> Boxes        {            get            {                return this.boxes;            }            set            {                this.boxes = value;                this.RaisePropertyChanged(Boxes);            }        }        OptionEnum CurrentEnum = OptionEnum.Quick;        public OneBoxViewModel()        {            Boxes = new ObservableCollection<BaseBox>();            Messenger.Default.Register<SelectorCommunicator>(this, (emp) =>            {                DrawBox(emp.SelectedAssets,emp.Option);            });        }        public void DrawBox(List<string> id, OptionEnum Option)        {            if (CurrentEnum!=Option)            {                Boxes = new ObservableCollection<BaseBox>();                CurrentEnum = Option;            }            switch(Option)            {                case OptionEnum.HighLow:                    List<string> WhatExist1 = Boxes.OfType<HighLowBox>().Select(key=>key.Box.AssetID.ToString()).ToList();                    List<string> WhatAdd1 = id.Except(WhatExist1).ToList();                    List<string> WhatRemove1 = WhatExist1.Except(id).ToList();                    foreach (string item in WhatAdd1)                    {                        Boxes.Add(new HighLowBox(int.Parse(item), SocketHandler.Socket));                    }                    foreach(string item in WhatRemove1)                    {                        HighLowBox box = Boxes.OfType<HighLowBox>().Where(key => key.Box.AssetID.ToString() == item).Select(key => key).FirstOrDefault();                        box.Dispose();                        Boxes.Remove(box);                    }                break;                case OptionEnum.OneTouch:                    List<string> WhatExist2 = Boxes.OfType<OneTouchBox>().Select(key=>key.Box.AssetID.ToString()).ToList();                    List<string> WhatAdd2 = id.Except(WhatExist2).ToList();                    List<string> WhatRemove2 = WhatExist2.Except(id).ToList();                    foreach (string item in WhatAdd2)                    {                        Boxes.Add(new OneTouchBox(int.Parse(item), SocketHandler.Socket));                    }                    foreach(string item in WhatRemove2)                    {                        OneTouchBox box = Boxes.OfType<OneTouchBox>().Where(key => key.Box.AssetID.ToString() == item).Select(key => key).FirstOrDefault();                        box.Dispose();                        Boxes.Remove(box);                    }                break;                case OptionEnum.Quick:                    List<string> WhatExist = Boxes.OfType<Quickbox>().Select(key=>key.Box.AssetID.ToString()).ToList();                    List<string> WhatAdd = id.Except(WhatExist).ToList();                    List<string> WhatRemove = WhatExist.Except(id).ToList();                    foreach (string item in WhatAdd)                    {                        Boxes.Add(new Quickbox(int.Parse(item),SocketHandler.Socket));                    }                    foreach(string item in WhatRemove)                    {                        Quickbox box = Boxes.OfType<Quickbox>().Where(key => key.Box.AssetID.ToString() == item).Select(key => key).FirstOrDefault();                        box.Dispose();                        Boxes.Remove(box);                    }                break;                case OptionEnum.Range:                    List<string> WhatExist3 = Boxes.OfType<RangeBox>().Select(key=>key.Box.AssetID.ToString()).ToList();                    List<string> WhatAdd3 = id.Except(WhatExist3).ToList();                    List<string> WhatRemove3 = WhatExist3.Except(id).ToList();                    foreach (string item in WhatAdd3)                    {                        Boxes.Add(new RangeBox(int.Parse(item), SocketHandler.Socket));                    }                    foreach(string item in WhatRemove3)                    {                        RangeBox box = Boxes.OfType<RangeBox>().Where(key => key.Box.AssetID.ToString() == item).Select(key => key).FirstOrDefault();                        box.Dispose();                        Boxes.Remove(box);                    }                break;            }        }    }}Also i have such hierarchy public abstract class BaseBox{}public class QuickBox : BaseBox { }public class RangeBox: BaseBox  { }public class OneTouchBox: BaseBox { }public class HighLowBox: BaseBox { }Every case in that switch block contains very similar code. Could it be refactored to leverage generics?
How to use generic
c#;generics
Well done for spotting the duplication and wanting to fix it! You are correct that you can use generics to solve this problem. Here's some approximate code to start you off in the right direction:private void UpdateBoxes<T>(IEnumerable<string> ids) where T : BaseBox{    var currentBoxAssetIds = Boxes.OfType<T>().Select(key => key.Box.AssetID.ToString()).ToList();    var assetIdsToAdd = ids.Except(currentBoxAssetIds);    var assetIdsToRemove = currentBoxAssetIds.Except(ids);    foreach (string assetId in assetIdsToAdd)    {        // ** see below        var newBox = (T)Activator.CreateInstance(typeof(T), int.Parse(assetId), SocketHandler.Socket);        Boxes.Add(newBox );    }    foreach(string assetId in assetIdsToRemove)    {        var box = Boxes.OfType<T>().Select(key => key.Box).FirstOrDefault(box => box.AssetID.ToString() == item);        box.Dispose();        Boxes.Remove(box);    }}You'll notice that I've changed almost all of the names in your code because yours weren't very descriptive.** Creating the instances of the T is the most difficult part. You could solve that by adding properties on the base class and a parameterless constructor so you could simply do:var newBox = new T();newBox.Property1 = some value;There are lots of other ways you could solve it for example, by using reflection to instantiate the class.Update:var newBox = (T)Activator.CreateInstance(typeof(T), int.Parse(assetId), SocketHandler.Socket);Also why are you converting ints to strings to compare them? 