using System.Collections.Generic;
public static void Main() {
var context1 = new ListAndSetContext();
Console.WriteLine($"ListAndSetContext.list() returns {declTypeName(context1.list())}");
Console.WriteLine($"ListAndSetContext.set() returns {declTypeName(context1.@set())}");
var context2 = new ReadOnlyListAndSetContext();
Console.WriteLine($"ReadOnlyListAndSetContext.list() returns {declTypeName(context2.list())}");
Console.WriteLine($"ReadOnlyListAndSetContext.set() returns {declTypeName(context2.@set())}");
var context3 = new ListAndReadOnlySetContext();
Console.WriteLine($"ListAndReadOnlySetContext.list() returns {declTypeName(context3.list())}");
Console.WriteLine($"ListAndReadOnlySetContext.set() returns {declTypeName(context3.@set())}");
var context4 = new ReadOnlyListAndReadOnlySetContext();
Console.WriteLine($"ReadOnlyListAndReadOnlySetContext.list() returns {declTypeName(context4.list())}");
Console.WriteLine($"ReadOnlyListAndReadOnlySetContext.set() returns {declTypeName(context4.@set())}");
private static string declTypeName<T>(T expr) => typeof(T).Name;
private class ListAndSetContext : Context<Config, List<int>, HashSet<string>> {
public ListAndSetContext() : base(new Config()) {}
private class ReadOnlyListAndSetContext : Context<Config, IReadOnlyList<int>, HashSet<string>> {
public ReadOnlyListAndSetContext() : base(new Config()) {}
private class ListAndReadOnlySetContext : Context<Config, List<int>, IReadOnlySet<string>> {
public ListAndReadOnlySetContext() : base(new Config()) {}
private class ReadOnlyListAndReadOnlySetContext : Context<Config, IReadOnlyList<int>, IReadOnlySet<string>> {
public ReadOnlyListAndReadOnlySetContext() : base(new Config()) {}
public interface IConfig<out T0, out T1> where T0 : IReadOnlyList<int> where T1 : IReadOnlySet<string> {
public class Config : IConfig<List<int>, HashSet<string>> {
public List<int> list() => new List<int>(new []{ 1, 2, 3 });
public HashSet<string> @set() => new HashSet<string>(new []{ "a", "b", "c" });
public interface IContext<T0, T1> where T0 : IReadOnlyList<int> where T1 : IReadOnlySet<string> {
public class Context<C, T0, T1> : IContext<T0, T1> where C : IConfig<T0, T1> where T0 : IReadOnlyList<int> where T1 : IReadOnlySet<string> {
private readonly C _config;
public Context(C config) => this._config = config;
public T0 list() => _config.list();
public T1 @set() => _config.@set();