Can anyone explain why the conversion in the return in the switch statement doesn't compile in .net 4? I've updated the example to be more accurate to my situation. The factory itself isn't generic actually.
Even casting "as BaseProductProcessor" does not work IF I'm passing in a base Product (that's actually a StandardProduct). Now if I explicitly pass a StandardProduct type to the factory, then it's ok - but what I have defined is a Product type in all calling methods anyway :|
How to get around this?
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace testing
{
[TestClass]
public class Test
{
[TestMethod]//fails
public void TestFactoryMethodWithBaseTypePassed()
{
Product product = new testing.StandardProduct();
var pp = new testing.ProductProcessorFactory().Create(product);
Assert.IsNotNull(pp);//fails because T coming into create wasn't the derived type
}
[TestMethod]//passes
public void TestFactoryMethodWithExactType()
{
var pp = new testing.ProductProcessorFactory().Create(new testing.StandardProduct());
Assert.IsNotNull(pp);
}
}
public abstract class BaseProductProcessor<T> where T : Product
{
public T Product { get; set; }
public BaseProductProcessor(T product)
{
Product = product;
}
}
public class StandardProductProcessor : BaseProductProcessor<StandardProduct>
{
public StandardProductProcessor(StandardProduct product)
: base(product)
{
}
}
public class ProductProcessorFactory
{
public ProductProcessorFactory()
{
}
public BaseProductProcessor<T> Create<T>(T product) where T : Product
{
switch (product.ProductType)
{
case ProductType.Standard:
var spp = new StandardProductProcessor(product as StandardProduct);
return spp as BaseProductProcessor<T>;//Nulls if T passed with a Product.. how to explicitly say T is a StandardProduct right here in the factory method so it's centralized?
}
return null;// spp as BaseProductProcessor<T>;
}
}
public class Product
{
public ProductType ProductType { get; set; }
}
public enum ProductType
{
Standard,
Special
}
public class StandardProduct : Product
{
}
}
That's because StandardProductProcessor expects an object of type StandardProduct.
At design time you only know that you have a Product.
While every StandardProduct is a Product, that doesn't go the other way around. Not every Product is a StandardProduct, that's why you need to tell the compiler explicitly that you have a StandardProduct
Well, here you want to achieve covariance of template parameter. It is not possible with base classes, but it IS possible with intefaces. So, I suggest you to replace your abstract class BaseProductProcessor<T> with interface:
public interface IBaseProductProcessor<out T> where T : Product // out marks argument as covariant
{
T Product { get; } // absense of setter is crusial here - otherwise you'll violate type safety
}
StandartProcessor:
public class StandardProductProcessor : IBaseProductProcessor<StandardProduct>
{
public StandardProductProcessor(StandardProduct product)
{
Product = product;
}
public StandardProduct Product { get; private set; }
}
and with this, just modify your factory function as following:
public class ProductProcessorFactory
{
public ProductProcessorFactory()
{
}
public IBaseProductProcessor<T> Create<T>(T product) where T : Product
{
switch (product.ProductType)
{
case ProductType.Standard:
var spp = new StandardProductProcessor(product as StandardProduct);
return spp as IBaseProductProcessor<T>;//no more nulls!
}
return null;
}
}
With this modifications, both of your tests will pass.
If you want to learn more about covariance and contravariance(out and in keywords in C#), I recommend the excellent series in Eric Lippert's blog (start with the bottom ones)
Related
Background
I have code that receives some deserialized data of type IProduct but the implementing class is unknown at runtime. I'm supposed to pass this data to an overloaded method that accepts an instance of the implementing class.
This can be achieved by using a switch statement, but it will look clunky and would require alot of code. I've solved this by using late-binding and runtime compilation for single entities but I'm unable to figure out how to do this for collections.
Solving the problem for single entities
If I have an object of type IProduct and want to pass this to the correct overloaded method that accepts an implementing class like Toy, Food, Car or something else. How do I achieve this without creating a big switch statement?
Given the following methods and interface:
public interface IProduct
{
string Name { get;}
double Price { get;}
}
public void Store(Apple apple);
public void Store(Toy toy);
public void Store(Car car);
With the switch statement it would look something like this:
IProduct product = new Apple();
switch (product)
{
case Apple apple:
Store(apple);
break;
case Toy toy:
Store(toy);
break;
case Car car:
Store(car);
break;
}
I've managed to reduce this to the following using late-binding and runtime compilation.
IProduct product = new Apple();
Store((dynamic)product);
Question
However, I've not been able to figure out how to do late-binding in a similar fashion when it comes to collections.
Given the following methods:
public static void Store(ICollection<Apple> apples);
public static void Store(ICollection<Toy> toys);
public static void Store(ICollection<Car> cars);
How do I pass this:
ICollection<IProduct> products = new List<IProduct>() { new Apple()};
Is there a way to achieve the same thing without using alot of magical code?
I'm not sure where these Store methods of yours are located. but something like this implementation is what seemed to me as the correct way to do things:
public interface IProduct
{
string Name { get;}
double Price { get;}
void Store(IProduct product);
}
public class Apple : IProduct
{
public Apple(string name, double price)
{
Name = name;
Price = price;
}
public string Name { get; }
public double Price { get; }
public void Store(IProduct product)
{
throw new NotImplementedException();
}
}
public class Toy : IProduct
{
public Toy(string name, double price)
{
Name = name;
Price = price;
}
public string Name { get; }
public double Price { get; }
public void Store(IProduct product)
{
throw new NotImplementedException();
}
}
public class Playground
{
void Test()
{
IProduct apple = new Apple("apple", 11);
ICollection<IProduct> apples = new List<IProduct>() { new Apple("apple", 230)};
apple.Store(apple);
IProduct toy = new Toy("toy", 11);
ICollection<IProduct> toys = new List<IProduct>() { new Toy("toy", 230)};
}
}
I have the following classes
public abstract class BaseViewPresenter { }
public abstract class BaseView<T> : UserControl
where T : BaseViewPresenter { }
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter> { }
I have a method that looks like this (simplified)
public BaseView<BaseViewPresenter> Resolve(BaseViewPresenter model)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
// Correctly creates BaseView object
var control = Activator.CreateInstance(viewType);
// Fails to cast as BaseView<BaseViewPresenter> so returns null
return control as BaseView<BaseViewPresenter>;
}
When I call this using an instances of LoginPresenter
var login = new LoginPresenter();
var ctl = Resolve(login);
The line Activator.CreateInstance(viewType) correctly resolves into a new instances of my LoginView, however control as BaseView<BaseViewPresenter> can't do the cast correctly so returns null.
Is there a way to correctly cast the control into BaseView<BaseViewPresenter> without using specific type generics?
Since LoginView inherits from BaseView<LoginPresenter>, and LoginPresenter inherits from BaseViewPresenter, I would assume there's a way to convert LoginView to BaseView<BaseViewPresenter>.
I am stuck with using .Net 3.5
This is a very frequently asked question. Let's rename your types:
abstract class Fruit { } // was BaseViewPresenter
abstract class FruitBowl<T> where T : Fruit // was BaseView
class Apple : Fruit { } // was LoginPresenter
class BowlOfApples : FruitBowl<Apple> { } // was LoginView
Your question now is:
I have a BowlOfApples, which inherits from FruitBowl<Apple>. Why can I not use it as a FruitBowl<Fruit>? An apple is a fruit, so a bowl of apples is a bowl of fruit.
No, it isn't. You can put a banana in a bowl of fruit, but you can't put a banana in a bowl of apples, and therefore a bowl of apples is not a bowl of fruit. (And by similar argument, a bowl of fruit is not a bowl of apples either.) Since the operations you can legally perform on the two types are different, they cannot be compatible.
Here is a photo of StackOverflow legend Jon Skeet demonstrating this fact:
The feature you want is called generic contravariance, and it is supported only on interfaces and delegate types when the compiler can prove that the variance is safe, and when the varying type is a reference type. For example, you can use an IEnumerable<Apple> in a context where IEnumerable<Fruit> is needed because the compiler can verify that there is no way that you can put a Banana into a sequence of fruit.
Do a search on "C# covariance and contravariance" on this site or on the web and you'll find many more details about how this feature works. In particular, my series of articles on how we designed and implemented this feature in C# 4 starts here: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx
I accepted Eric's answer since it provides a great explanation of why what I wanted wasn't possible, but I also thought I'd share my solution in case anyone else runs into this same problem.
I removed the generic type parameter from my original BaseView class, and created a 2nd version of the BaseView class that included the generic type parameter and specifics for it.
The first version is used by my .Resolve() method or other code that doesn't care about the specific types, and the second version is used by any code that does care, such as the implentation of a BaseView
Here's an example of how my code ended up looking
// base classes
public abstract class BaseViewPresenter { }
public abstract class BaseView : UserControl
{
public BaseViewPresenter Presenter { get; set; }
}
public abstract class BaseView<T> : BaseView
where T : BaseViewPresenter
{
public new T Presenter
{
get { return base.Presenter as T; }
set { base.Presenter = value; }
}
}
// specific classes
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter>
{
// Can now call things like Presenter.LoginPresenterMethod()
}
// updated .Resolve method used for obtaining UI object
public BaseView Resolve(BaseViewPresenter presenter)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
BaseView view = Activator.CreateInstance(viewType) as BaseView;
view.Presenter = presenter;
return view;
}
You're expecting to treat the type as being covariant with respect to the generic argument. Classes can never be covariant; you'd need to use an interface rather than (or in addition to) an abstract class to make it covariant with respect to T. You'd also need to be using C# 4.0.
My usual solution to this problem is to create an intermediary class that has access to the type-parametric class's methods through delegates. Fields can also be accessed through getters/setters.
The general pattern goes:
public abstract class Super {}
public abstract class MyAbstractType<T> where T : Super {
public MyGeneralType AsGeneralType() {
return MyGeneralType.Create(this);
}
// Depending on the context, an implicit cast operator might make things
// look nicer, though it might be too subtle to some tastes.
public static implicit operator MyGeneralType(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
public int field;
public void MyMethod1() {}
public void MyMethod2(int argument) {}
public abstract bool MyMethod3(string argument);
}
public delegate T Getter<T>();
public delegate void Setter<T>(T value);
public delegate void MyMethod1Del();
public delegate void MyMethod2Del(int argument);
public delegate bool MyMethod3Del(string argument);
public class MyGeneralType {
public Getter<int> FieldGetter;
public Setter<int> FieldSetter;
public MyMethod1Del MyMethod1;
public MyMethod2Del MyMethod2;
public MyMethod3Del MyMethod3;
public static MyGeneralType Create<T>(MyAbstractType<T> t) where T : Super {
var g = new MyGeneralType();
g.FieldGetter = delegate { return t.field; };
g.FieldSetter = value => { t.field = value; };
g.MyMethod1 = t.MyMethod1;
g.MyMethod2 = t.MyMethod2;
g.MyMethod3 = t.MyMethod3;
return g;
}
public int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
The above exemplifies getting all the methods and fields but normally I only need a few of them. This is a general solution to the problem and one could feasibly write a tool to generate these intermediary classes automatically, which I might at some point.
Try it here: https://dotnetfiddle.net/tLkmgR
Note that this is enough for all my cases, but you can be extra hacky with this:
public abstract class MyAbstractType<T> where T : Super {
// ... Same everything else ...
// data fields must become abstract getters/setters, unfortunate
public abstract int field {
get;
set;
}
public static implicit operator MyAbstractType<Super>(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
}
public class MyGeneralType : MyAbstractType<Super> {
// ... same constructors and setter/getter
// fields but only keep method fields
// that contain the method references for
// implementations of abstract classes,
// and rename them not to clash with the
// actual method names ...
public MyMethod3Del myMethod3Ref;
// Implement abstract methods by calling the corresponding
// method references.
public override bool MyMethod3(string argument) {
return myMethod3Ref(argument);
}
// Same getters/setters but with override keyword
public override int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
And there you go, now you can literally cast a MyAbstractType<Sub> where Sub : Super to a MyAbstractType<Super>, although it's no longer the same object anymore, but it does retain the same methods and data, it's sort of a complex pointer.
public class Sub : Super {}
public class MySubType : MyAbstractType<Sub> {
public int _field;
public override int field {
get { return _field; }
set { _field = value; }
}
public override bool MyMethod3(string argument) {
Console.WriteLine("hello " + argument);
return argument == "world";
}
}
public class MainClass {
public static void Main() {
MyAbstractType<Sub> sub = new MyAbstractType<Sub>();
MyAbstractType<Super> super = sub;
super.MyMethod3("hello"); // calls sub.MyMethod3();
super.field = 10; // sets sub.field
}
}
This isn't as good in my opinion, the other version of MyGeneralType is a more straighforward layer over the concrete types, plus it doesn't require rewriting the data fields, but it does actually answer the question, technically. Try it here: https://dotnetfiddle.net/S3r3ke
Example
Using these abstract classes:
public abstract class Animal {
public string name;
public Animal(string name) {
this.name = name;
}
public abstract string Sound();
}
public abstract class AnimalHouse<T> where T : Animal {
List<T> animals;
public AnimalHouse(T[] animals) {
this.animals = animals.ToList();
}
public static implicit operator GeneralAnimalHouse(AnimalHouse<T> house) {
return GeneralAnimalHouse.Create(house);
}
public List<string> HouseSounds() {
return animals.Select(animal => animal.Sound()).ToList();
}
}
We make this "general" variant:
public delegate List<string> HouseSoundsDel();
public class GeneralAnimalHouse {
public HouseSoundsDel HouseSounds;
public static GeneralAnimalHouse Create<T>(AnimalHouse<T> house) where T : Animal {
var general = new GeneralAnimalHouse();
general.HouseSounds = house.HouseSounds;
return general;
}
}
And finally with these inheritors:
public class Dog : Animal {
public Dog(string name) : base(name) {}
public override string Sound() {
return name + ": woof";
}
}
public class Cat : Animal {
public Cat(string name) : base(name) {}
public override string Sound() {
return name + ": meow";
}
}
public class DogHouse : AnimalHouse<Dog> {
public DogHouse(params Dog[] dogs) : base(dogs) {}
}
public class CatHouse : AnimalHouse<Cat> {
public CatHouse(params Cat[] cats) : base(cats) {}
}
We use it like this:
public class AnimalCity {
List<GeneralAnimalHouse> houses;
public AnimalCity(params GeneralAnimalHouse[] houses) {
this.houses = houses.ToList();
}
public List<string> CitySounds() {
var random = new Random();
return houses.SelectMany(house => house.HouseSounds())
.OrderBy(x => random.Next())
.ToList();
}
}
public class MainClass {
public static void Main() {
var fluffy = new Cat("Fluffy");
var miu = new Cat("Miu");
var snuffles = new Cat("Snuffles");
var snoopy = new Dog("Snoopy");
var marley = new Dog("Marley");
var megan = new Dog("Megan");
var catHouse = new CatHouse(fluffy, miu, snuffles);
var dogHouse = new DogHouse(snoopy, marley, megan);
var animalCity = new AnimalCity(catHouse, dogHouse);
foreach (var sound in animalCity.CitySounds()) {
Console.WriteLine(sound);
}
}
}
Output:
Miu: meow
Snoopy: woof
Snuffles: meow
Fluffy: meow
Marley: woof
Megan: woof
Notes:
I added names so it's clear that the method references carry their owner's data with them, for those unfamiliar with delegates.
The required using statements for this code are System, System.Collections.Generic, and System.Linq.
You can try it here: https://dotnetfiddle.net/6qkHL3#
A version that makes GeneralAnimalHouse a subclass of AnimalHouse<Animal> can be found here: https://dotnetfiddle.net/XS0ljg
I have been battling with this bit of code for a while now and I am trying to get a solution as it is literally the last part before it goes to testing.
I have the following interfaces and classes (simplified to the relevant parts):
public interface ITagParent<T> where T : ITag
{
List<TagAddOn<T>> TagCollection { get; set; }
}
public interface ITag
{
int Id { get; set; }
string Description { get; set; }
TagGroup TagGroup { get; set; }
}
public class TagAddOn<T> : ViewModelBase where T : ITag
{
private T _currentTag;
public T CurrentTag
{
get { return _currentTag; }
set { _currentTag = value; }
}
}
public partial class Customer : ITagParent<CustomerTag>
{
List<TagAddOn<CustomerTag>> _tagCollection;
public List<TagAddOn<CustomerTag>> TagCollection
{
get { return _tagCollection; }
set { _tagCollection = value; }
}
}
public partial class CustomerTag : ITag
{
public int Id { get; set; }
}
public class TagAddOnManager
{
public static string GetTagCurrentValue(List<TagAddOn<ITag>> dataObjectAddOns)
{
// LOTS OF SNIPPING!
return string.Empty;
}
}
I am trying to use the GetTagCurrentValue method in the TagAddOnManager class like this:
string value = TagAddOnManager.GetTagCurrentValue(
((ITagParent<ITag>)gridCell.Row.Data).TagCollection));
Everything compiles fine, but errors when trying to cast gridCell.Row.Data to ITagParent<ITag>. I understand this is due to covarience and a workaround (if not a terribly safe one) is to mark T in the ITagParent interface with the out keyword, but that won't work as you can see it is used in the TagCollection property, which can't be read only.
I tried casting the above to ITagParent<CustomerTag>, but this fails at compile time with a 'cannot convert' error when trying to feed it into my GetTagCurrentValue method.
Another option I considered is using some base classes instead of the ITagParent interface, but that won't work as the Customer object already inherits from another base class, which can't be modified for this implementation.
I know I could just overload the GetTagCurrentValue method with List<TagAddOn<CustomerTag>> as the parameter type and all other variations, but that really seems like a 'I give up' solution. I could probably use reflection to get the desired results, but that would be unwieldy and not very efficient, especially considering this method could be called a lot in a particular process.
So does anyone have any suggestions?
Could you use something like that
public class TagAddOnManager
{
public static string GetTagCurrentValue<TTag>(ITagParent<TTag> tagParent)
where TTag : ITag
{
// Just an example.
return tagParent.TagCollection.First().CurrentTag.Description;
}
}
and use it like that?`
var value = TagAddOnManager.GetTagCurrentValue((Customer)CustomergridCell.Row.Data);
I have the following base class
public abstract class BaseRepository<T>
{
public abstract IEnumerable<T> GetAll();
}
And a class the inherits it.
public class CustomerRepository: BaseRepository<Customer>
{
public override IEnumerable<Customer>GetAll()
{
return null;
}
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
what i want to do is using this class
public class Sales
{
public int Id { get; set; }
public int CustomerId {get;set;}
public decimal Total {get;set;}
}
this doesn't work
public class SalesRepository: BaseRepository<Sales>
{
public override IEnumerable<Sales>GetAll(IEnumerable<Customer> Customers)
{
return null;
}
}
My question is, how to I modify my BaseClass to have optional ienumerable parameters of that i can then use as needed.
The GetAll(IEnumerable<Customer> Customers) function amounts to a new method. It does not have the same signature of the base, and so cannot be overridden in this way. The SalesRepository class, if it is to be a BaseRepository<Sales>, must implement the GetAll() method as is.
You can do this change
public class SalesRepository : BaseRepository<Sales>
{
public override IEnumerable<Sales> GetAll()
{
return GetAll(null);
}
public IEnumerable<Sales> GetAll(IEnumerable<Customer> Customers)
{
return null;
}
}
BaseRepository<Sales> rep = new SalesRepository();
rep.GetAll();
this will call overridden version and makes a call to GetAll(null).
To pass value to GetAll() method you need to have do the following
SalesRepository srep = new SalesRepository();
srep.GetAll(new Customer[] { new Customer() });
You can either mark parameter as optional or you can make overloads to the method in your base class, both of which will result in the same thing. When you mark a parameter as optional the compiler simply makes the overloads for you.
Ultimately you probably need to make two methods in your base class and then either hide one (make private) in your implementation of each parent class or have it throw an error. If you can figure out a good way to have default values then that may work as well.
I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:
public interface ISomeType<V>
{
V Value {get; set;}
}
public interface ISomeTypeWrapper
{
object Value { get; set; }
}
public class SomeTypeWrapper<T> : ISomeTypeWrapper
where T : ISomeType<???>
{
T someType;
public SomeTypeWrapper(T wrappedSomeType)
{
someType = wrappedSomeType
}
public object Value
{
get { return someType.Value; }
set { someType.Value = value != null ? value : default(T); }
}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.
I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.
How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)
How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?
You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.
container
.Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
.Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());
You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.
Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:
public class SomeTypeWrapperFactory
{
public ISomeType<int> CreateWrapper(SomeType1 someType1)
{
return new SomeType1Wrapper(someType1);
}
public ISomeType<string> CreateWrapper(SomeType2 someType2)
{
return new SomeType2Wrapper(someType2);
}
}
public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }
Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.
Why SomeTypeWrapper but not SomeObjectWrapper?
public class SomeObjectWrapper : ISomeType
{
Object _someObject;
PropertyInfo _valuePropertyInfo;
public SomeObjectWrapper(Object wrappedSomeObject)
{
_someObject = wrappedSomeObject;
_valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
}
public object Value
{
get { return _valuePropertyInfo.GetValue(_someObject, null); }
set { _valuePropertyInfo.SetValue(_someObject, value, null); }
}
}
Edited With .NET 3.5 using LinFu
You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution.
In that case I would personally choose Orsol's solution.
However: here's an example with LinFu's ducktyping.
public interface ISomeType {
object Value{get; set;}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeWrapperFactory
{
public static ISomeType CreateSomeTypeWrapper(object aSomeType)
{
return aSomeType.CreateDuck<ISomeType>();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
foreach(var o in someTypes)
{
Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
}
Console.ReadLine();
}
}
Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).
With .NET 4 using dynamic
See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern.
In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeVisitor
{
public void VisitAll(object[] someTypes)
{
foreach(var o in someTypes) {
// this should be in a try-catch block
Console.WriteLine(((dynamic) o).Value);
}
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
var vis = new SomeTypeVisitor();
vis.VisitAll(someTypes);
}
}