In the following code, i have an overloaded method, one that takes a parameter of type ClazzA and the other of type ClazzB. In the code shown, the first GetDescription method (the one that takes ClazzA as a parameter) is called. I think i understand why.
My question is..is there an elegant way of having the method that takes clazzB called first if the underlying object is of type classB (without having to inspect each object and casting it to clazzB)?
public class ClazzA
{
public virtual string Descr { get { return "A"; } }
}
public class ClazzB : ClazzA
{
public override string Descr { get { return "B"; } }
}
public static class test
{
public static void Main()
{
ClazzA test = new ClazzB();
GetDecription(test);
}
public static void GetDecription(ClazzA someClazz)
{
Debug.WriteLine("I am here");
}
public static void GetDecription(ClazzB someClazz)
{
Debug.WriteLine("I want to be here");
}
}
Output: "I am here"
I really want the 2nd method to be called since 'test' is of type ClassB. Curerently the only two solutions i have is:
if (test is ClazzB)
return GetDescription( (ClazzB) test );
or
In ClassA do pretty much the same thing...check the type and delegate to the 2nd method
Both of these require inspection of the object to determine its type
Overloads are determined at compile time. The compile time type of the reference is ClazzA so that overload is chosen. What you are asking for is related to multiple dispatch. C# and many other languages like C++ and Java only support single dispatch (via virtual methods). There are a number of ways people have come up with to work around this. The purest OO way of doing this is the visitor pattern. You modify the classes to contain a method (Accept) which then passes the this reference to a method on the visitor (Visit). This works because you override the Accept method in each subclass so that this will be the object's actual type. All the visitor needs is a specific method for each subclass that you want to support (see wikipedia for more details).
A sample:
public class ClazzA
{
public virtual string Accept(ClassVisitor visitor)
{
return visitor.Visit(this);
}
}
public class ClazzB : ClazzA
{
public override string Accept(ClassVisitor visitor)
{
return visitor.Visit(this);
}
}
public abstract class ClassVisitor
{
public abstract string Visit(ClazzA a);
public abstract string Visit(ClazzB b);
}
public class GetDescriptionVisitor : ClassVisitor
{
public override string Visit(ClazzA a)
{
return "A";
}
public override string Visit(ClazzB b)
{
return "B";
}
}
Usage:
ClassVisitor visitor = new GetDescriptionVisitor();
ClazzA b = new ClazzB();
Console.WriteLine(b.Accept(visitor)); // prints "B"
Because the method overload resolution occurs at compile-time. In terms of dealing with this situation, if you are using C# 4 then you could use dynamic so that the overload resolution is deferred to execution-time.
dynamic instance = new ClazzB();
Console.WriteLine(GetDescription(instance));
Alternatively, you could use a Visitor Pattern something like the following but this double-dispatch approach feels like a lot of work. Note the repetitive Visit method that must be re-implement in every derived type!
public interface IVisitable
{
string Visit(DescriptionVisitor visitor);
}
public class ClazzA : IVisitable
{
public virtual string Visit(DescriptionVisitor visitor)
{
return visitor.Visit(this);
}
}
public class ClazzB : ClazzA
{
public override string Visit(DescriptionVisitor visitor)
{
return visitor.Visit(this);
}
}
public class DescriptionVisitor
{
public string Visit(ClazzA item) { return "Description A"; }
public string Visit(ClazzB item) { return "Description B"; }
}
Then the following will ultimately still call the overload in DescriptionVisitor that takes ClazzB.
var visitor = new DescriptionVisitor();
ClazzA a = new ClazzB();
Console.WriteLine(a.Visit(visitor));
What you're trying to do is probably better performed using polymorphism, like so:
public interface IProvideDescription {
string GetDescription();
}
public class A : IProvideDescription {
public string GetDescription() {
return "I'm an A";
}
}
public class B : IProvideDescription {
public string GetDescription() {
return "I'm a B";
}
}
// to execute:
IProvideDescription x = new A();
Console.WriteLine(x.GetDescription());
x = new B();
Console.WriteLine(x.GetDescription());
To answer the question in your title ("...why is the base class given precedence?"), look at what your variable test is declared as (answer: your base class). When the overload is selected, all the method call knows is that you're passing a variable of type ClazzA into it. Sure, you've assigned it an object of type ClazzB, but suppose your assignment statement was more complex:
ClazzA test = GiveMeSomeObject();
The method selection has to occur at compile time to provide type safety.
You can get the behaviour you want by using the "dynamic" keyword which was introduced in .Net 4.0. It evaluates the type at runtime and will pick the right overload.
public static class test
{
public static void Main()
{
dynamic test = new ClazzB();
GetDecription(test);
}
public static void GetDecription(ClazzA someClazz)
{
Debug.WriteLine("I am here");
}
public static void GetDecription(ClazzB someClazz)
{
Debug.WriteLine("I want to be here");
}
}
Generally it's not a responsibility of external class to identify class type.
if you need a polymorphic behavior, just put GetDescription into ClassA as virtual function and then override in ClassB - that will be conceptually correct.
As #roken mentioned, your example will actually result in B since the Descr property is overridden. If this is all you're doing, remove the ClazzB overload and use the polymorphic behavior you've already got. If you actually need to do something different in the methods and overloading is the best way to do that, you could do it via dynamic overload resolution:
GetDecription((dynamic)test);
However, this has some drawbacks, such as performance and a lack of compile-time testing that GetDescription(test) makes sense. I'd recommend doing a runtime check within GetDecription(ClazzA):
if (someClazz is ClazzB)
{
GetDescription((ClazzB)someClazz);
return;
}
You can get by with just a single GetDescription() method:
public String GetDescription(ClassA in) {
if (in is ClassB) {
return (in as ClassB).Descr
}
return in.Descr;
}
Related
I have the following base class (omitted version):
class BaseClass
{
}
I create the following derived classes:
class DataPreparationClass<T> : BaseClass
{
}
class DataClass<T,U> : DataPreparationClass<T>
{
public virtual void Start<U>(U arg)
{}
}
class DataClassMain : DataClass<InputData,Data>
{
public override void Start(Data argument)
{
base.Start(argument);
}
}
class DataClassAux : DataClass<InputData,AuxData>
{
public override void Start(AuxData argument)
{
base.Start(argument);
}
}
I have a List<BaseClass> containing various derived instances (there are more derived types) and I intend to call their Start method respectively:
List<BaseClass> instances = GetAllInstance();
foreach(BaseClass instance in instances)
{
object arg = GetArgsForInstance(instance);
// instance.Start(arg); //can't call this
}
However, as their common base is the BaseClass, I can't call Start without casting to...basicly every possible type as their types are unknown at the processing.
If I use dynamic:
((dynamic)target).Start(new Data("starting")); //target is of type DataClassMain<InputData,Data>
I get an exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'The best
overloaded method match for
'Client.DataClass<InputData,Data>.Start(Data)' has some invalid
arguments'
So how should I call the unknown method?
So, the most straight forward answer to your question would be to use pattern matching to call the start method.
List<BaseClass> instances = GetAllInstance();
foreach(BaseClass instance in instances)
{
object arg = GetArgsForInstance(instance);
switch(instance){
case DataClassMain d : d.Start((Data)arg); break;
case DataClassAux a : a.Start((AuxData)arg);break;
default: throw new Exception();
}
}
But I do get the feeling this is an convoluted and inappropriate inheritance chain, and you should really consider using a factory and/or strategy pattern instead.
It's assumed that GetArgsForInstance allways will return the correct type with respect to the type it receives as an argument, and that the return types (Data, AuxData and so on) share a common base type. So we could do the type resolution directly with a signature of T GetArgsForInstance<T>(BaseClass b). That way you can make sure you get args of the right type before you return it.
Since the Start overrides just pass along the call generic types, so the overrides in DataClassMain and DataClassAux are unnecessary.
If we modify DataClass a bit we can then do it like this:
class DataClass<T,U> : DataPreparationClass<T>
{
public virtual void Start(U arg)
{
//Do somethin with arg
}
public void Call(Func<BaseClass,U> f){
U data = f.Invoke(this);
Start(data);
}
}
and invoke it with
List<BaseClass> instances = GetAllInstance();
foreach(BaseClass instance in instances)
{
switch(instance)
{
case DataClassMain d : d.Call(GetArgsForInstance<Data>); break;
case DataClassAux a : a.Call(GetArgsForInstance<AuxData>);break;
default: throw new Exception();
}
}
The reason this is preferable is that we can let the compiler ensure that we only pass the appropriate types to the different methods, no casting needed.
But again, such a convoluted inheritance chain should almost always be avoided.
I would say, your questions shows multiple flaws in your model:
by definition of your classes, there is no polymorphism inbetween you Start() methods : Start(Data) do not override Start<U>(U)
by definition of your GetArgsForInstance() method, you have lost the type information you need.
I would add that Classes that are called Classes and Data that are called Data and that are parameterized with their content are way too generic.
That saying, your question implies that you are not wanting to fix those flaws, maybe they are out of your control, so you have to live with it :
instead of not loosing the Type information, you ask for a way to retrieve it.
instead of using polymorphism to retrieve the type from the best place to retrieve do so (in my opinion), which is the Start method itself, you ask for a way to retrieve it in the calling code.
So, what I would try to do is :
rework your GetArgsForInstance() method to be able not to loose this information, for instance, replace it by an object, something like :
class DataClassMain : DataClass<InputData,Data>
{
public override void Start(ArgumentProvider argumentProvider)
{
Data argument = argumentProvider.getArgumentAsData(argumentProvider);
base.Start(argument);
}
}
if not possible, retrieve the types from the inside of the derived classes, for instance something like :
public class DataClassMain : DataClass<InputData,Data>
{
public override void Start(object arg)
{
base.Start(arg);
Data argAsData = (Data) arg;
}
}
if not possible, that means you already have a set of constraint that is making your code hard to maintain, so let's go for a messy reflective thing, but you have to be aware that there is no polymorphism involved and get rid of your 'override' and 'virtual' modifier on Start() methods. Here is a fully working program, which output is :
DataClassMain
DataClassAux
public static void Main(string[] args)
{
List<BaseClass> instances = GetAllInstance();
foreach(BaseClass instance in instances)
{
object value = GetArgsForInstance(instance);
messyInvoke(instance, value);
}
}
private static void messyInvoke(BaseClass instance, object value)
{
MethodInfo method = instance.GetType().GetMethod("Start");
if (method != null)
{
ParameterInfo[] parametersInfos = method.GetParameters();
if (parametersInfos.Length == 1)
{
object[] paramArray = {value};
method.Invoke(instance, paramArray);
}
}
}
public class BaseClass{
public virtual Type GetTypeOfArgs()
{
return typeof(Toto);
}
}
public class DataPreparationClass<T> : BaseClass {}
public abstract class DataClass<T> : DataPreparationClass<T>
{
}
public class DataClassMain : DataClass<Toto>
{
public void Start(Data arg)
{
Console.WriteLine("DataClassMain");
}
}
public class DataClassAux : DataClass<Toto>
{
public void Start(AuxData argument)
{
Console.WriteLine("DataClassAux");
}
}
private static object GetArgsForInstance(BaseClass isntance)
{
if (isntance is DataClassMain)
return new Data();
if (isntance is DataClassAux)
return new AuxData();
throw new ArgumentException();
}
private static List<BaseClass> GetAllInstance()
{
return new List<BaseClass> {new DataClassMain(), new DataClassAux()};
}
public class Toto{}
public class DataClassInputData
{
}
public class Data : DataClassInputData
{
}
public class AuxData : DataClassInputData
{
}
Problem description
I am trying to store a collection of generic Foo<T> elements, where T may be different for each item. I also have functions like DoSomething<T>(Foo<T>) that can accept a Foo<T> of any T. It seems like I should be able to call this function on each element of the abovementioned list, because they are all valid parameters for the function, but I can't seem to express this idea to the C# compiler.
The problem, as far as I can tell, is that I can't really express a list like that, because C# does not allow me to write Foo<T> without binding T. What I would want is something like Java's wildcard mechanism (Foo<?>). Here is how it might look in a Pseudo-C#, where this wildcard type existed:
class Foo<T> {
// ...
}
static class Functions {
public static void DoSomething<T>(Foo<T> foo) {
// ...
}
public static void DoSomething(List<Foo<?>> list) {
foreach(Foo<?> item in list)
DoSomething(item);
}
}
This pattern is valid in Java, but how can I do the same in C#? I have experimented a bit to find solutions which I'll post in an answer below, but I feel that there should be a better way.
Note: I have already solved this problem "well enough" for my practical needs, and I know ways to work around it (e.g. using the dynamic type), but I'd really like to see if there is a simpler solution that does not abandon static type safety.
Just using object or a nongeneric supertype, as has been suggested below, does not allow me to call functions that require a Foo<T>. However, this can be sensible even if I don't know anything about T. For example, I could use the Foo<T> to retrieve a List<T> list from somewhere, and a T value from somewhere else, and then call list.Add(value) and the compiler will know that all the types work out right.
Motivation
I was asked why I would ever need something like this, so I'm making up an example that is a bit closer to the everyday experience of most developers. Imagine that you are writing a bunch of UI components which allow the user to manipulate values of a certain type:
public interface IUiComponent<T> {
T Value { get; set; }
}
public class TextBox : IUiComponent<string> {
public string Value { get; set; }
}
public class DatePicker : IUiComponent<DateTime> {
public DateTime Value { get; set; }
}
Apart from the Value property, the components will have have many other members of course (e.g. OnChange events).
Now let's add an undo system. We shouldn't have to modify the UI elements themselves for this, because we have access to all the relevant data already--Just hook up the OnChange events and whenever the user changes a UI component, we store away the value of each IUiComponent<T> (A bit wasteful, but let's keep things simple). To store the values we will use a Stack<T> for each IUiComponent<T> in our form. Those lists are accessed by using the IUiComponent<T> as key. I'll leave out the details of how the lists are stored (If you think this matters I'll provide an implementation).
public class UndoEnabledForm {
public Stack<T> GetUndoStack<T>(IUiComponent<T> component) {
// Implementation left as an exercise to the reader :P
}
// Undo for ONE element. Note that this works and is typesafe,
// even though we don't know anything about T...
private void Undo<T>(IUiComponent<T> component) {
component.Value = GetHistory(component).Pop();
}
// ...but how do we implement undoing ALL components?
// Using Pseudo-C# once more:
public void Undo(List<IUiComponent<?>> components) {
foreach(IUiComponent<?> component in components)
Undo(component);
}
}
We could undo everything by directly calling Undo<T>() on all the IUiComponents (by name):
public void Undo(List<IUiComponent<?>> components) {
Undo(m_TextBox);
Undo(m_DatePicker);
// ...
}
However, I want to avoid this, because it means you will have to touch one more place in the code if you add/remove a component. If you have tens of fields and more functions that you want to perform on all the components (e.g. write all their values to a database and retrieve them again), this can become a lot of duplication.
Sample Code
Here is a small piece of code that you can use to develop/check a solution. The task is to put several Pair<T>-objects into some kind of collection object, and then call a function which accepts this collection object and swaps the First and Second field of each Pair<T> (using Application.Swap()). Ideally, you should not use any casts or reflection. Bonus points if you can manage to do it without modifying the Pair<T>-class in any way :)
class Pair<T> {
public T First, Second;
public override string ToString() {
return String.Format("({0},{1})", First, Second);
}
}
static class Application {
static void Swap<T>(Pair<T> pair) {
T temp = pair.First;
pair.First = pair.Second;
pair.Second = temp;
}
static void Main() {
Pair<int> pair1 = new Pair<int> { First = 1, Second = 2 };
Pair<string> pair2 = new Pair<string> { First = "first", Second = "second" };
// imagine more pairs here
// Silly solution
Swap(pair1);
Swap(pair2);
// Check result
Console.WriteLine(pair1);
Console.WriteLine(pair2);
Console.ReadLine();
}
}
I would suggest you define an interface to invoke the functions you'll want to call as DoSomething<T>(T param). In simplest form:
public interface IDoSomething
{ void DoSomething<T>(T param); }
Next define a base type ElementThatCanDoSomething:
abstract public class ElementThatCanDoSomething
{ abstract public void DoIt(IDoSomething action); }
and a generic concrete type:
public class ElementThatCanDoSomething><T>
{
T data;
ElementThatCanDoSomething(T dat) { data = dat; }
override public void DoIt(IDoSomething action)
{ action.DoIt<T>(data); }
}
Now it's possible to construct an element for any type compile-time T, and pass that element to a generic method, keeping type T (even if the element is null, or if the element is of a derivative of T). The exact implementation above isn't terribly useful, but it can be easily extended in many useful ways. For example, if type T had generic constraints in the interface and concrete type, the elements could be passed to methods which had those constraints on its parameter type (something which is otherwise very difficult, even with Reflection). It may also be useful to add versions of the interface and invoker methods that can accept pass-through parameters:
public interface IDoSomething<TX1>
{ void DoSomething<T>(T param, ref TX1 xparam1); }
... and within the ElementThatCanToSomething
abstract public void DoIt<TX1>(IDoSomething<TX1> action, ref TX1 xparam1);
... and within the ElementThatCanToSomething<T>
override public void DoIt<TX1>(IDoSomething<TX1> action, ref TX1 xparam1)
{ action.DoIt<T>(data, ref xparam1); }
The pattern may easily be extended to any number of pass-through parameters.
EDIT 2: in the case of your overhauled question, the approach is basically the same I've proposed you earlier.
Here I'm adapting it to your scenario and commenting better on what makes it work (plus an unfortunate "gotcha" with value types...)
// note how IPair<T> is covariant with T (the "out" keyword)
public interface IPair<out T> {
T First {get;}
T Second {get;}
}
// I get no bonus points... I've had to touch Pair to add the interface
// note that you can't make classes covariant or contravariant, so I
// could not just declare Pair<out T> but had to do it through the interface
public class Pair<T> : IPair<T> {
public T First {get; set;}
public T Second {get; set;}
// overriding ToString is not strictly needed...
// it's just to "prettify" the output of Console.WriteLine
public override string ToString() {
return String.Format("({0},{1})", First, Second);
}
}
public static class Application {
// Swap now works with IPairs, but is fully generic, type safe
// and contains no casts
public static IPair<T> Swap<T>(IPair<T> pair) {
return new Pair<T>{First=pair.Second, Second=pair.First};
}
// as IPair is immutable, it can only swapped in place by
// creating a new one and assigning it to a ref
public static void SwapInPlace<T>(ref IPair<T> pair) {
pair = new Pair<T>{First=pair.Second, Second=pair.First};
}
// now SwapAll works, but only with Array, not with List
// (my understanding is that while the Array's indexer returns
// a reference to the actual element, List's indexer only returns
// a copy of its value, so it can't be switched in place
public static void SwapAll(IPair<object>[] pairs) {
for(int i=0; i < pairs.Length; i++) {
SwapInPlace(ref pairs[i]);
}
}
}
That's more or less it... Now in your main you can do:
var pairs = new IPair<object>[] {
new Pair<string>{First="a", Second="b"},
new Pair<Uri> {
First=new Uri("http://www.site1.com"),
Second=new Uri("http://www.site2.com")},
new Pair<object>{First=1, Second=2}
};
Application.SwapAll(pairs);
foreach(var p in pairs) Console.WriteLine(p.ToString());
OUTPUT:
(b,a)
(http://www.site2.com/,http://www.site1.com/)
(2,1)
So, your Array is type-safe, because it can only contain Pairs (well, IPairs). The only gotcha is with value types. As you can see I had to declare the last element of the array as a Pair<object> instead of Pair<int> as I would have liked.
This is because covariance/contravariance don't work with value types so I had to box int in an object.
=========
EDIT 1 (old, just leaving there as reference to make sense of the comments below):
you could have both a non-generic marker interface for when you need to act on the container (but don't care about the "wrapped" type) and a covariant generic one for when you need the type information.
Something like:
interface IFoo {}
interface IFoo<out T> : IFoo {
T Value {get;}
}
class Foo<T> : IFoo<T> {
readonly T _value;
public Foo(T value) {this._value=value;}
public T Value {get {return _value;}}
}
Suppose you have this simple hierarchy of classes:
public class Person
{
public virtual string Name {get {return "anonymous";}}
}
public class Paolo : Person
{
public override string Name {get {return "Paolo";}}
}
you could have functions that work either on any IFoo (when you don't care if Foo wraps a Person) or specifically on IFoo<Person> (when you do care):
e.g.
static class Functions
{
// this is where you would do DoSomethingWithContainer(IFoo<?> foo)
// with hypothetical java-like wildcards
public static void DoSomethingWithContainer(IFoo foo)
{
Console.WriteLine(foo.GetType().ToString());
}
public static void DoSomethingWithGenericContainer<T>(IFoo<T> el)
{
Console.WriteLine(el.Value.GetType().ToString());
}
public static void DoSomethingWithContent(IFoo<Person> el)
{
Console.WriteLine(el.Value.Name);
}
}
which you could use like this:
// note that IFoo can be covariant, but Foo can't,
// so we need a List<IFoo
var lst = new List<IFoo<Person>>
{
new Foo<Person>(new Person()),
new Foo<Paolo>(new Paolo())
};
foreach(var p in lst) Functions.DoSomethingWithContainer(p);
foreach(var p in lst) Functions.DoSomethingWithGenericContainer<Person>(p);
foreach(var p in lst) Functions.DoSomethingWithContent(p);
// OUTPUT (LinqPad)
// UserQuery+Foo`1[UserQuery+Person]
// UserQuery+Foo`1[UserQuery+Paolo]
// UserQuery+Person
// UserQuery+Paolo
// anonymous
// Paolo
One notable thing in the output is that even the function that only received IFoo still had and printed the full type information which in java would have been lost with type erasure.
It seems that in C#, you have to create a list of Foo, which you use as base type of Foo<T>. However, you can't easily get back to Foo<T> from there.
One solution I found is to add an abstract method to Foo for each function SomeFn<T>(Foo<T>), and implement them in Foo<T> by calling SomeFn(this). However, that would mean that every time you want to define a new (external) function on Foo<T>, you have to add a forwarding function to Foo, even though it really shouldn't have to know about that function:
abstract class Foo {
public abstract void DoSomething();
}
class Foo<T> : Foo {
public override void DoSomething() {
Functions.DoSomething(this);
}
// ...
}
static class Functions {
public static void DoSomething<T>(Foo<T> foo) {
// ...
}
public static void DoSomething(List<Foo> list) {
foreach(Foo item in list)
item.DoSomething();
}
}
A slightly cleaner solution from a design perspective seems to be a Visitor pattern which generalizes the above approach to a degree and severs the coupling between Foo and the specific generic functions, but that makes the whole thing even more verbose and complicated.
interface IFooVisitor {
void Visit<T>(Foo<T> foo);
}
class DoSomethingFooVisitor : IFooVisitor {
public void Visit<T>(Foo<T> foo) {
// ...
}
}
abstract class Foo {
public abstract void Accept(IFooVisitor foo);
}
class Foo<T> : Foo {
public override void Accept(IFooVisitor foo) {
foo.Visit(this);
}
// ...
}
static class Functions {
public static void DoSomething(List<Foo> list) {
IFooVisitor visitor = new DoSomethingFooVisitor();
foreach (Foo item in list)
item.Accept(visitor);
}
}
This would almost be a good solution IMO, if it was easier to create a Visitor. Since C# apparently does not allow generic delegates/lambdas, you cannot specify the visitor inline and take advantage of closures though - As far as I can tell, each Visitor needs to be a new explicitly defined class with possible extra parameters as fields. The Foo type also has to explicitly support this scheme by implementing the Visitor pattern.
For those who may still find this interesting, here is the best solution I could come up with that also meets the "bonus requirement" of not touching the original type in any way. It is basically a Visitor pattern with the twist that we don't store the Foo<T> directly in our container, but rather store a delegate which calls an IFooVisitor on our Foo<T>. Notice how we can easily make a list of those because T is not actually part of the delegates' type.
// The original type, unmodified
class Pair<T> {
public T First, Second;
}
// Interface for any Action on a Pair<T>
interface IPairVisitor {
void Visit<T>(Pair<T> pair);
}
class PairSwapVisitor : IPairVisitor {
public void Visit<T>(Pair<T> pair) {
Application.Swap(pair);
}
}
class PairPrintVisitor : IPairVisitor {
public void Visit<T>(Pair<T> pair) {
Console.WriteLine("Pair<{0}>: ({1},{2})", typeof(T), pair.First, pair.Second);
}
}
// General interface for a container that follows the Visitor pattern
interface IVisitableContainer<T> {
void Accept(T visitor);
}
// The implementation of our Pair-Container
class VisitablePairList : IVisitableContainer<IPairVisitor> {
private List<Action<IPairVisitor>> m_visitables = new List<Action<IPairVisitor>>();
public void Add<T>(Pair<T> pair) {
m_visitables.Add(visitor => visitor.Visit(pair));
}
public void Accept(IPairVisitor visitor) {
foreach (Action<IPairVisitor> visitable in m_visitables)
visitable(visitor);
}
}
static class Application {
public static void Swap<T>(Pair<T> pair) {
T temp = pair.First;
pair.First = pair.Second;
pair.Second = temp;
}
static void Main() {
VisitablePairList list = new VisitablePairList();
list.Add(new Pair<int> { First = 1, Second = 2 });
list.Add(new Pair<string> { First = "first", Second = "second" });
list.Accept(new PairSwapVisitor());
list.Accept(new PairPrintVisitor());
Console.ReadLine();
}
}
Output:
Pair<System.Int32>: (2,1)
Pair<System.String>: (second,first)
I have few concrete which uses the following type of interface
interface IActivity<T>
{
bool Process(T inputInfo);
}
Concrete classes are like as follows
class ReportActivityManager :IActivity<DataTable>
{
public bool Process(DataTable inputInfo)
{
// Some coding here
}
}
class AnalyzerActivityManager :IActivity<string[]>
{
public bool Process(string[] inputInfo)
{
// Some coding here
}
}
Now how can i write the factory class which retuns a generic interface some thing like IActivity.
class Factory
{
public IActivity<T> Get(string module)
{
// ... How can i code here
}
}
Thanks
You should create generic method, otherwise compiler will not know type of T in return value. When you will have T you will be able to create activity based on type of T:
class Factory
{
public IActivity<T> GetActivity<T>()
{
Type type = typeof(T);
if (type == typeof(DataTable))
return (IActivity<T>)new ReportActivityManager();
// etc
}
}
Usage:
IActivity<DataTable> activity = factory.GetActivity<DataTable>();
Often this is implemented as in lazyberezovsky's answer. In c++ you could use template specialization to get compiler errors when you try to create a type the factory does not handle.
You can't do that in C# but you can get close. Though the code might look a little surprising which in turn could be a problem.
public static class Factory {
public static IActivity<someType> Get(this someType self){
//stuff specific to someType
}
public static IActivity<someOtherType> Get(someOtherType self){
//stuff specific to someOtherType
}
public static T Creator<T>(){
return null;
}
}
The usage would then be
IActivity<someType> act = Factory.Creator<someType>().Get();
of course this only works if you can pass a concrete type. If you need to pass a type parameter things get more complicated.
One of the features/topics discussed in OOP are Virtual members. I am looking at a statement as following:
Virtual members dispatch on run-time type
Does it mean a virtual method rely on type of object(s) it is accepting or dealing with rather variable type?
Any correction or comment will be appreciated.
Thanks,
Amit
No. It has nothing to do with the parameters that the method accepts as those should be the same for each implementation. It means that the virtual method will be resolved at run time based on the type the method is being called on. Consider this:
public class Parent
{
public virtual string SayHi()
{
return "Hi!";
}
}
public class NiceChild : Parent
{
public override string SayHi()
{
return "Hello World!";
}
}
public class MeanChild : Parent
{
public override string SayHi()
{
return "You suck!";
}
}
Now, we have a method:
public void PrintHi(Parent instance)
{
Console.WriteLine(instance.SayHi());
}
You could call that method one of three ways but not know the outcome until runtime if all you saw was the method above:
PrintHi(new Parent()); // Hi
PrintHi(new NiceChild()); // Hello World!
PrintHi(new MeanChild()); // You suck!
Coming from a C++ background, I've run into a snag with overloading based on a specific instance of a generic type. The following doesn't work since only once instance of the code for the Foo<T> class is ever generated, so inside the Method, the type of this is simply Foo<T>, not Foo<A> or Foo<B> as I'd hoped. In C++ I'm used to templates being instantiated as unique types.
using System.Collections.Generic;
class A
{
// Concrete class
}
class B
{
// Concrete class
}
class Bar
{
public void OverloadedMethod(Foo<A> a) {} // do some A related stuff
public void OverloadedMethod(Foo<B> b) {} // do some B related stuff
public void OverloadedMethod(OtherFoo of) {} // do some other stuff
public void VisitFoo(FooBase fb) { fb.Method(this); }
}
abstract class FooBase
{
public abstract void Method(Bar b);
}
class Foo<T> : FooBase
{
// Class that deals with As and Bs in an identical fashion.
public override void Method(Bar b)
{
// Doesn't compile here
b.OverloadedMethod(this);
}
}
class OtherFoo : FooBase
{
public override void Method(Bar b)
{
b.OverloadedMethod(this);
}
}
class Program
{
static void Main(string[] args)
{
List<FooBase> ListOfFoos = new List<FooBase>();
ListOfFoos.Add(new OtherFoo());
ListOfFoos.Add(new Foo<A>());
ListOfFoos.Add(new Foo<B>());
Bar b = new Bar();
foreach (FooBase fb in ListOfFoos)
b.VisitFoo(fb);
// Hopefully call each of the Bar::Overloaded methods
}
}
Is there a way to get something like this to work in C#? I'd rather not have to duplicate the code in Foo as separate classes for every type I want to use it for.
Edit:
Hopefully this is a little clearer.
I now have a genuinely complete piece of code which demonstrates the problem. Note to OP: please try compiling your code before posting it. There were a bunch of things I had to do to get this far. It's good to make it as easy as possible for other people to help you. I've also removed a bunch of extraneous bits. OtherFoo isn't really relevant here, nor is FooBase.
class A {}
class B {}
class Bar
{
public static void OverloadedMethod(Foo<A> a) { }
public static void OverloadedMethod(Foo<B> b) { }
}
class Foo<T>
{
// Class that deals with As and Bs in an identical fashion.
public void Method()
{
// Doesn't compile here
Bar.OverloadedMethod(this);
}
}
Yes, this doesn't compile. What did you expect it to do, exactly? Bear in mind that the overload resolution is performed at compile time, not execution time. As fallen888 says, you could cast and call the appropriate overloaded method - but which of the two overloads would you expect the compiler to pick otherwise? What do you want it to do with Foo<string> instead of Foo<A> or Foo<B>?
This all goes to demonstrate that .NET generics are indeed significantly different from C++ templates, of course...
I haven't tried it but it seems you should be able to achieve what you want by making A & B visitable (e.g. with the acyclic visitor pattern).
This works for the static case. Dealing with instance functions would be a bit more complicated. This post from Jon Skeet might provide a reasonable way to deal with instance methods.
class Program
{
static void Main(string[] args)
{
var testA = new Foo<A>();
testA.Method();
var testB = new Foo<B>();
testB.Method();
Console.ReadLine();
var testString = new Foo<string>(); //Fails
testString.Method();
Console.ReadLine();
}
}
class A { }
class B { }
class Bar
{
public static void OverloadedMethod(Foo<A> a)
{
Console.WriteLine("A");
}
public static void OverloadedMethod(Foo<B> b)
{
Console.WriteLine("B");
}
}
class Foo<T>
{
static Foo()
{
overloaded = (Action<Foo<T>>)Delegate.CreateDelegate(typeof(Action<Foo<T>>), typeof(Bar).GetMethod("OverloadedMethod", new Type[] { typeof(Foo<T>) }));
}
public void Method()
{
overloaded(this);
}
private static readonly Action<Foo<T>> overloaded;
}
Edit: I'm not sure that you can complete this as you're attempting. I've tried all sorts of tricks to attempt to get this to work and can't get it to compile. The best I can do is to pull the method call outside of my Generic class. If your method call is outside, then you can specifically define what T is in the generic. However, inside the method, at compile time, the compiler doesn't know what T will be so it doesn't know which overloaded method to call. The only way I can see around this is to use a switch to determine the type of T and manually specify the overload to call.
The best I can do is this, which isn't quite what you're after, but it could be used to a similar effect:
class Stuff<T>
{
public T value { get; set; }
}
class Program
{
static void DummyFunc(Stuff<int> inst)
{
Console.WriteLine("Stuff<int>: {0}", inst.value.ToString());
}
static void DummyFunc(Stuff<string> inst)
{
Console.WriteLine("Stuff<string>: {0}", inst.value);
}
static void DummyFunc(int value)
{
Console.WriteLine("int: {0}", value.ToString());
}
static void DummyFunc(string value)
{
Console.WriteLine("string: {0}", value);
}
static void Main(string[] args)
{
var a = new Stuff<string>();
a.value = "HelloWorld";
var b = new Stuff<int>();
b.value = 1;
var c = "HelloWorld";
var d = 1;
DummyFunc(a);
DummyFunc(b);
DummyFunc(c);
DummyFunc(d);
}
}
and got output:
Stuff<string>: HelloWorld
Stuff<int>: 1
string: HelloWorld
int: 1
I've got four overloaded functions referencing two referencing generic classes (one for int and one for string) and two referencing regular types (one for int and one for string) and it all works okay... is this what you're after?
Edit: The problem doesn't seem to be with the calling of the overloaded methods, it has to do with your foreach which is trying to convert all items in the list to the same type as the first in order to reference the overloaded method. The first item that doesn't conform to that exact definition will cause your compile to fail.
I was hoping to find an easier way to do this but for now I'm going with this:
Replace Foo<T> class with these classes:
abstract class Foo<T> : FooBase
{
// Class that deals with As and Bs in an identical fashion.
}
class Foo_A : Foo<A>
{
public override void Method(Bar b)
{
b.OverloadedMethod(this);
}
}
class Foo_B : Foo<B>
{
public override void Method(Bar b)
{
// Doesn't compile here
b.OverloadedMethod(this);
}
}
And change the instantiations to
List<FooBase> ListOfFoos = new List<FooBase>();
ListOfFoos.Add(new OtherFoo());
ListOfFoos.Add(new Foo_A());
ListOfFoos.Add(new Foo_B());
This at least doesn't require dublicating the code in Foo<T>, and just requires me to forward the constructors.