using System;
using System.Linq;
/* Interfaces */
public interface IArgumentClass
{
void IArgumentClassMethod();
}
public interface ISpecialArgumentClass
{
void ISpecialArgumentClassMethod();
}
public interface IContainerClass
{
void IContainerClassClassMethod();
}
/* Argument types */
public class ArgumentClass0 : IArgumentClass
{
public void IArgumentClassMethod(){}
}
public class SpecialArgumentClass0 : IArgumentClass, ISpecialArgumentClass
{
public void IArgumentClassMethod(){}
public void ISpecialArgumentClassMethod(){}
}
public class SpecialArgumentClass1 : IArgumentClass, ISpecialArgumentClass
{
public void IArgumentClassMethod() { }
public void ISpecialArgumentClassMethod() { }
}
/* Container types */
public class GenericContainer<T> : IContainerClass
where T : IArgumentClass, new()
{
public T t = new T();
public void IContainerClassClassMethod() { }
}
public class NonGenericContainer : IContainerClass
{
public void IContainerClassClassMethod(){}
}
/* main program */
public class Test
{
public static void Main()
{
// Instantiate
IContainerClass[] containers =
{
new GenericContainer<ArgumentClass0>(),
new GenericContainer<SpecialArgumentClass0>(),
new GenericContainer<SpecialArgumentClass1>(),
new NonGenericContainer()
};
// We want to call IContainerClassClassMethod methods on all instances:
foreach (IContainerClass container in containers)
container.IContainerClassClassMethod();
// We want to call ISpecialArgumentClassMethod on instances where it's possible:
foreach (IContainerClass container in containers)
{
if (container.GetType().IsGenericType && container.GetType().GetGenericTypeDefinition() == typeof(GenericContainer<>))
{
foreach (Type typeArgument in container.GetType().GetGenericArguments())
{
if (typeArgument.GetInterfaces().Contains(typeof(ISpecialArgumentClass)))
{
// Next line is a compilation error. How can I get a similar result?
GenericContainer<ISpecialArgumentClass> mySpecializedClassWithSpecialArgument = container as GenericContainer<ISpecialArgumentClass>;
mySpecializedClassWithSpecialArgument.t.ISpecialArgumentClassMethod();
}
}
}
}
}
}