using System.Collections.Generic;
public enum NumberOfConvertedObjs {
public interface IErrorHandler{
void CardinalityError(string safName, NumberOfConvertedObjs expected, int actual);
public static class IConvertedObjectExtensions {
public static void VisitAs<T>(this IConvertedObject convObj, Action<T> specificSingleObjHandler, Action<IEnumerable<CSModelObject>> multipleObjectHandler, IErrorHandler eH) {
specificSingleObjHandler(correctTyped);
multipleObjectHandler(objList);
public static void VisitAsSingle<T>(this IConvertedObject convObj, Action<T> specificSingleObjHandler, IErrorHandler eH) {
specificSingleObjHandler(correctTyped);
eH.CardinalityError(convObj.Name, NumberOfConvertedObjs.One, objList.Count());
public class CSModelObject{
public interface IConvertedObject{
void Visit(Action<CSModelObject> singleObjHandler, Action<IEnumerable<CSModelObject>> multipleObjectHandler);
TOut Visit<TOut>(Func<CSModelObject,TOut> singleObjHandler, Func<IEnumerable<CSModelObject>,TOut> multipleObjectHandler);
public class SingleConvertedObj : IConvertedObject {
public SingleConvertedObj(CSModelObject val) {_val = val;}
public void Visit(Action<CSModelObject> singleObjHandler, Action<IEnumerable<CSModelObject>> multipleObjectHandler){
public TOut Visit<TOut>(Func<CSModelObject,TOut> singleObjHandler, Func<IEnumerable<CSModelObject>,TOut> multipleObjectHandler){
return singleObjHandler(_val);
public class MultipleConvertedObj : IConvertedObject {
IEnumerable<CSModelObject> _val;
public MultipleConvertedObj(IEnumerable<CSModelObject> val) {_val = val;}
public void Visit(Action<CSModelObject> singleObjHandler, Action<IEnumerable<CSModelObject>> multipleObjectHandler){
multipleObjectHandler(_val);
public TOut Visit<TOut>(Func<CSModelObject,TOut> singleObjHandler, Func<IEnumerable<CSModelObject>,TOut> multipleObjectHandler){
return multipleObjectHandler(_val);
public static void Main()
Dictionary<string,IConvertedObject> context = new Dictionary<string,IConvertedObject>();
var singleModelObject = new CSModelObject();
context.Add("A", new SingleConvertedObj(singleModelObject));
var multipleObjs = new List<CSModelObject>() {new CSModelObject(), new CSModelObject()};
context.Add("B", new MultipleConvertedObj(multipleObjs));
var convertedObj = context["A"];
o => Console.WriteLine("do something with single obj"),
foreach(var item in oList)
Console.WriteLine("do something with all objs in a list");
public string Date{get;set;}