Мне нравится Муджахид Дауд Хан ответ за использование шаблонов C# 8.0. Для полиморфного c способа, я считаю, что статья - это TLDR: P
На базовом уровне c мы можем сделать что-то вроде этого:
using System;
using System.Collections.Generic;
namespace ConsoleApp4
{
class Program
{
static void Main()
{
var builder = new IconSelectorBuilder();
Console.WriteLine($"{nameof(Device.DevIsIOS)}, false");
foreach (var item in builder.Build(Device.DevIsIOS, false).GetIcons())
{
Console.WriteLine(item);
}
Console.WriteLine($"{nameof(Device.DevIsIOS)}, true");
foreach (var item in builder.Build(Device.DevIsIOS, true).GetIcons())
{
Console.WriteLine(item);
}
//Console.WriteLine($"{nameof(Device.Other)}, false");
//foreach (var item in builder.Build(Device.Other, false).GetIcons())
//{
// Console.WriteLine(item);
//}
//Console.WriteLine($"{nameof(Device.Other)}, true");
//foreach (var item in builder.Build(Device.Other, true).GetIcons())
//{
// Console.WriteLine(item);
//}
}
}
public enum Device
{
DevIsIOS,
Other
}
public class IconSelectorBuilder
{
public IIconSelector Build(Device device, bool showIcons)
{
return device switch
{
Device.DevIsIOS => new DevIsIOSIconSelector(showIcons),
_ => new OtherIconSelector(showIcons),
};
}
}
public interface IIconSelector
{
public bool ShowIcons { get; set; }
IEnumerable<Icon> GetIcons();
}
public abstract class IconSelectorBase : IIconSelector
{
public bool ShowIcons { get; set; }
protected IconSelectorBase(bool showIcons)
{
ShowIcons = showIcons;
}
protected abstract IEnumerable<Icon> GetHideIcons();
protected abstract IEnumerable<Icon> GetShowIcons();
public IEnumerable<Icon> GetIcons() => ShowIcons ? GetShowIcons() : GetHideIcons();
}
public sealed class DevIsIOSIconSelector : IconSelectorBase
{
public DevIsIOSIconSelector(bool showIcons) : base(showIcons)
{
}
protected override IEnumerable<Icon> GetHideIcons()
{
yield return new Icon
{
IconType = IconType.GT,
MyProperty1 = 0,
MyProperty2 = 0,
};
yield return new Icon
{
IconType = IconType.FR2,
MyProperty1 = 1,
MyProperty2 = 0,
};
}
protected override IEnumerable<Icon> GetShowIcons()
{
yield return new Icon
{
IconType = IconType.FR1,
MyProperty1 = 0,
MyProperty2 = 0,
};
yield return new Icon
{
IconType = IconType.GT,
MyProperty1 = 1,
MyProperty2 = 0,
};
yield return new Icon
{
IconType = IconType.FR2,
MyProperty1 = 2,
MyProperty2 = 0,
};
}
}
public sealed class OtherIconSelector : IconSelectorBase
{
public OtherIconSelector(bool showIcons) : base(showIcons)
{
}
protected override IEnumerable<Icon> GetHideIcons()
{
// TODO
throw new NotImplementedException();
}
protected override IEnumerable<Icon> GetShowIcons()
{
// TODO
throw new NotImplementedException();
}
}
public class Icon
{
public IconType IconType { get; set; }
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
public override string ToString() => $"{IconType}, {MyProperty1}, {MyProperty2}";
}
public enum IconType
{
FR1,
GT,
FR2,
CE
}
}
Идея состоит в том, чтобы создать IconSelectorBuilder
и укажите такие параметры, как App.devIsIOS
/ whatever
, App.ShowIcons
/ whatever
(я предположил bool). Затем мы создаем правильный класс, который наследуется от IconSelectorBase
, который предоставляет logi c для параметра bool (App.ShowIcons
/ 'any'). Тогда соответствующий класс вернет правильные значки.
Вывод:
DevIsIOS, false
GT, 0, 0
FR2, 1, 0
DevIsIOS, true
FR1, 0, 0
GT, 1, 0
FR2, 2, 0