It is going to be hard to explain why Im doing the things im about to show you, but they have a reason so stay with me here. (suggestions are welcome).
I have a Functor which invokes a method on its input.
!Please note! the functor is actually an extension method so there must be a typing inference.
Also, I have an abstract class with 2 childs and an interface which demands a method signature.
The example code looks like this:
public sealed class AbstractionTester
{
internal static void Run()
{
// The functor here accepts A type but in my original code its just a generic type.
// I wanted to keep it simple for this example only
Func<A, bool> func = a =>
{
a.CallMe(); //Displays "Error"
return true;
};
B obj = new B();
func(obj);
}
}
internal interface ICallMe<T>
where T : MyEntity
{
T CallMe();
}
//Just a class which holds data I would like to store about every object I have, for example: CreateDate
internal abstract class MyEntity
{ }
internal abstract class A : MyEntity, ICallMe<A>
{
//some other fields i would like to store..
// This method here must never be invoked
public A CallMe()
{
//throw new Exception();
Console.WriteLine("Error");
return this;
}
}
internal class B : A, ICallMe<B>
{
public new B CallMe()
{
Console.WriteLine("B");
return this;
}
}
internal class C : A, ICallMe<C>
{
public new C CallMe()
{
Console.WriteLine("C");
return this;
}
}
Everytime I call Run() the result is the Error is yeilded to the screen.
What can I do to enforce that this functor I have won't execute the method in the parent class.
Functor will never receive an instance of A anyway, because A is abstract (I mean pure A, not child of A)
Additional info:
I must explicity write the return types of CallMe in class B and C. I CANNOT change them to type A.
I need to keep the type of A (or something similar) in the functor because I need to infer the type for some code continuation.
It is really weird implementation. Why dont you use Visitor pattern?
Then you can do:
static void Main(string[] args)
{
Element a = new A();
Element b = new B();
Element c = new C();
ICallMe callMe = new CallMe();
a.accept(callMe);
b.accept(callMe);
c.accept(callMe);
}
Implementation below:
public interface ICallMe
{
void Visit(A a);
void Visit(B b);
void Visit(C c);
}
public class CallMe : ICallMe
{
public void Visit(A c)
{
Console.WriteLine("A");
}
public void Visit(B b)
{
Console.WriteLine("B");
}
public void Visit(C a)
{
Console.WriteLine("C");
}
}
interface Element
{
void accept(ICallMe visitor);
}
public class A : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
public class B : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
public class C : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
Here is a solution that works without defining public A CallMe() as virtual. This has the benefit that child classes can define their CallMe() as new so they can return B or C. But it requires that you can make the classes public instead of internal (or you will get an error).
Use dynamic dispatch to call the actual runtime type instead of the type declared in the interface:
Func<A, bool> func = a => {
var runtimeType = (dynamic)a;
runtimeType.CallMe();
return true;
};
.net Fiddle
There is a specific language feature for this; interface reimplementation.
Reimplement explicitly the interface and make the generic functor take an ICallable<T>:
internal class B : A, ICallMe<B>
{
B ICallable<B>.CallMe()
{
Console.WriteLine("B");
return this;
}
}
internal class C : A, ICallMe<C>
{
B ICallable<C>.CallMe()
{
Console.WriteLine("B");
return this;
}
}
And your functor should be:
Func<T, bool> func = a => ...
And T should be constrained (at method or class level) to ICallable<T>.
UPDATE: If the functor is really an extension code, I'm not sure what the issue is:
public static bool MyEnxtensionMethod<T>(T argument)
where T: ICallable<T>
{
argument.CallMe();
return true;
}
Why do you need to keep A anywhere?
The best way to ensure that A's CallMe method is never invoked is for it to not exist.
internal abstract class MyEntity
{ }
internal abstract class A : MyEntity
{ }
Now it can never be invoked as you required.
Now make the interface covariant:
internal interface ICallMe<out T>
where T : MyEntity
{
T CallMe();
}
Then change Func<A, bool> to Func<ICallMe<A>, bool>
public sealed class AbstractionTester
{
internal static void Run()
{
// The functor here accepts A type but in my original code its just a generic type.
// I wanted to keep it simple for this example only
Func<ICallMe<A>, bool> func = a =>
{
a.CallMe(); //Displays "B"
return true;
};
B obj = new B();
func(obj);
}
}
Related
I have the following classes (I can't change them, they are not in my control):
public abstract class BusinessBase { }
public class A : BusinessBase { }
public class B : BusinessBase { }
public class FooOne
{
public void Foo<T>(FooDelegates.Func<T> func) where T : BusinessBase { ... }
}
public class FooTwo
{
public void Foo<T>(FooDelegates.Func<T> func) where T : BusinessBase { ... }
}
public static class FooDelegates
{
public delegate TResult Func<TResult>();
}
Creating a delegate and calling the method is pretty straightforward:
var f1 = new FooOne();
f1.Foo(() => new A());
However, trying to use reflection to do this is proving to be a bit complicated. I have the following function which I cannot seem to finish:
public class GenericHelper
{
// Parent can be A or B or etc...
// Child is FooOne or FooTwo or etc...
public void Relate(object parent, object child)
{
var mi = child.GetType().GetMethod("Foo");
var gmi = mi.MakeGenericMethod(parent.GetType());
// This next part obviously won't compile...
var del = typeof(FooDelegates.Func<>).MakeGenericType(parent.GetType());
FooDelegates.Func<parent.GetType()> del = () => parent;
gmi.Invoke(child, new object[] { del });
}
}
How do I correctly generate a FooDelegates.Func<T> where T is the parent type and I have an anonymous method as the assigned method?
You can use expression trees to compile new functions at runtime:
Expression.Lambda(del, Expression.Constant(parent)).Compile()
I have hierarchy of classes:
class A{}
class B: A {}
class C:B {}
is it possible to implement method in class A and it would be inherited by derived classes B and C and so on and that method should return value of class type?
A val = A.method(); (val is A)
B val = B.method(); (val is B)
C val = C.method(); (val is C)
And I don't want use of generics in call of this method, ie:
C val = C.method<C>();
Guys, excuse me, one elaboration, this method should be static.
I don't want to use generic in method istelf, because it forces to point type that method should return, whereas method should return type of its class.
class A
{
Method<T>()
{
T result;
return result;
}
}
If I have such method I can change return type:
D result = A.Method<D>();
but I wanted it to return value of type A;
No, that is not possible.
To call the method like that it would have to be static, and static methods are not inherited.
Using B.method() to call a static method in A is the same as using A.method(). The compiler just uses the type to determine where the method is, but it's impossible for the method to know if it was called using the A or B type.
Use an extension method:
class Program
{
static void Main(string[] args)
{
B x = new B();
x.Method();
}
}
public static class Ext
{
public static T Method<T>(this T obj)
where T : A,new()
{
return new T();
}
}
public class A
{
}
public class B : A
{
}
Or a variation thereof. Note that you must have some public member capable of creating an instance of the specified type. To expound, the compiler 'guesses' the value of the type parameter. The method is still generic, but generic syntax is nowhere to be seen when the method is called (usually).
Using some design patterns from C++ makes this easier:
class A
{
protected virtual A method_impl() { return new A(); }
public A method() { return method_impl(); }
}
class B : A
{
protected override A method_impl() { return new B(); }
public new B method() { return (B)method_impl(); }
}
class C : B
{
protected override A method_impl() { return new C(); }
public new C method() { return (C)method_impl(); }
}
Of course, this exact problem never arises in C++, which allows covariant return types for overrides.
Another way, using IoC pattern:
class A
{
protected virtual void method_impl(A a) { a.initialize(); }
public A method() { A result = new A(); method_impl(result); return result; }
}
class B : A
{
public new B method() { B result = new B(); method_impl(result); return result; }
}
class C : B
{
public new C method() { C result = new C(); method_impl(result); return result; }
}
in the following code I define an interface, an abstract base class with a method that prints "foo", a class that implements both, and an extension method on the interface with a signature equal to a method in the abstract base class that prints "bar". when I run this sample, why is "bar" printed instead of "foo"? and if applicable, what's the morale behind this language design choice?
public interface ISomething
{}
public abstract class SomethingElse
{
public void foo()
{
Console.WriteLine("foo");
}
}
public class DefinitelySomething : SomethingElse, ISomething
{}
public static class ISomethingExtensions
{
public static void foo(this ISomething graphic)
{
Console.WriteLine("bar");
}
}
class Program
{
static void Main(string[] args)
{
ISomething g = new DefinitelySomething();
g.foo();
}
}
ISomething does not have a member called foo, so the extension method will be called.
Because the variable is declared as ISomething.
The instance method is not known until run-time however the method overload resolution is at compile time. There's no guarantee that the instance actually has a suitable method. In you particular example it has but that's from a type safety perspective an irrelevant coincidence. The important type at the line g.foo() is the type that g is declared as not the run time type
The foo method on SomethingElse is not considered for overload resolution as you are acting on an instance of ISomething.
Or to think about it another way, consider what would happen if you didn't have any extension method? In this case you would get a compile error as no other suitable method could be found.
Try changing your code to the following:
DefinitelySomething g = new DefinitelySomething();
g.foo();
And it should behave how you are expecting.
In this case you call the foo method of the ISomething, and it is resolved into extension method.
If you use this code:
ISomething g = new DefinitelySomething();
(g as SomethingElse).foo();
you'll get the right output.
You could always check inside the extension method to see if the object you are currently using has an existing method with the exact same signature
public static System.Reflection.MethodInfo ExtensionOverrider(this Object obj, System.Reflection.MethodInfo method )
{
return obj.GetType().GetMethods().Where(
x => x.Name == method.Name &&
x.GetParameters().Select(z => z.ParameterType).SequenceEqual(method.GetParameters().Skip(1).Select(w => w.ParameterType))).FirstOrDefault();
}
public static void foo(this ISomething graphic)
{
var Method = graphic.ExtensionOverrider(System.Reflection.MethodBase.GetCurrentMethod());
if( Method != null)
Method.Invoke(graphic, new Object[0]{});
else
Console.WriteLine("bar");
}
Just some more examples, tested in LinqPad.
Note that the items declared as ISomething use the extension method and return "bar", which as #leppie pointed out is because ISomething does not have a method foo, but calling foo on the new instance directly gives the correct output "foo".
void Main(string[] args) {
// baseline
var g0 = new DefinitelyNothing(); g0.foo(); // "foo"
ISomething g;
// won't work, not ISomething
// g = new DefinitelyNothing(); g.foo();
g = new DefinitelyNothingThatThinksItsSomething(); g.foo(); // "bar"
new DefinitelyNothingThatThinksItsSomething().foo(); // "foo"
g = new DefinitelySomething(); g.foo(); // "bar"
new DefinitelySomething().foo(); // "foo"
g = new DefinitelySomethingWithFoo(); g.foo(); // "bar"
new DefinitelySomethingWithFoo().foo(); // "foo"
(g as IWithFoo).foo(); // "foo", not "qux"
g = new DefinitelySomethingFromNothingWithFoo(); g.foo(); // "bar"
new DefinitelySomethingFromNothingWithFoo().foo(); // "foo"
(g as ISomethingWithFoo).foo(); // "foo", not "baz"
IWithFoo g1;
g1 = new DefinitelyNothingWithFoo(); g1.foo(); // "foo"
new DefinitelyNothingWithFoo().foo(); // "foo"
}
public interface ISomething {}
public interface IWithFoo {
void foo();
}
public interface ISomethingWithFoo : ISomething, IWithFoo {}
public abstract class Nothing {
public void foo() { Console.WriteLine("foo"); }
}
public abstract class NothingWithFoo : IWithFoo {
public void foo() { Console.WriteLine("foo"); }
}
public abstract class Something : ISomething {
public void foo() { Console.WriteLine("foo"); }
}
public abstract class SomethingWithFoo : ISomethingWithFoo {
public void foo() { Console.WriteLine("foo"); }
}
public abstract class SomethingFromNothingWithFoo : Nothing, ISomethingWithFoo {}
public class DefinitelyNothing: Nothing {}
public class DefinitelyNothingThatThinksItsSomething: Nothing, ISomething {}
public class DefinitelyNothingWithFoo : NothingWithFoo {}
public class DefinitelySomething : Something {}
public class DefinitelySomethingWithFoo : SomethingWithFoo {}
public class DefinitelySomethingFromNothingWithFoo : SomethingFromNothingWithFoo {}
public static class ISomethingExtensions {
// http://en.wikipedia.org/wiki/Metasyntactic_variable
public static void foo(this ISomething whatever) { Console.WriteLine("bar"); }
public static void foo(this ISomethingWithFoo whatever) { Console.WriteLine("baz"); }
public static void foo(this IWithFoo whatever) { Console.WriteLine("qux"); }
}
Is it possible to create a user extendable visitor pattern in C#? (preferably .net 3.5)
I have a set of classes in a library that I wish to add functionality to with the visitor pattern. The problem is that it is also possible for the user of the library to create their own classes. This means that you need to create a special visitor that will accept the new class types but our Accept methods are setup to receive the base type. How can I get the derived classes to call the right method in the derived visitor.
Or is there another way of doing 'if this type, do this"?
Some example code:
/* In library */
namespace VisitorPattern.System
{
interface IThing
{
void Accept(SystemVisitor visitor);
void ThingMethodA(...);
void ThingMethodB(...);
}
class SystemThingA : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemThingB : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemThingC : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemVisitor
{
public SystemVisitor(object specialSystemServices) { }
public virtual void Visit(SystemThingA thing) { Console.WriteLine("SystemThingA"); }
public virtual void Visit(SystemThingB thing) { Console.WriteLine("SystemThingB"); }
public virtual void Visit(SystemThingC thing) { Console.WriteLine("SystemThingC"); }
public virtual void Visit(IThing thing) { Console.WriteLine("sysvis:IThing"); }
}
}
/* in user code */
namespace VisitorPattern.User
{
using VisitorPattern.System;
class UserThingA : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
...ThingMethods...
}
class UserThingB : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
...ThingMethods...
}
class UserThingC : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
...ThingMethods...
}
// ?????
class UserVisitor : SystemVisitor
{
public UserVisitor(object specialSystemServices, object specialUserServices) : base(specialSystemServices) { }
public void Visit(UserThingA thing) { Console.WriteLine("UserThingA"); }
public void Visit(UserThingB thing) { Console.WriteLine("UserThingB"); }
public void Visit(UserThingC thing) { Console.WriteLine("UserThingC"); }
public override void Visit(IThing thing) { Console.WriteLine("uservis:IThing"); }
}
class Program
{
static void Main(string[] args)
{
var visitor = new UserVisitor("systemservice", "userservice");
List<IThing> mylist = new List<IThing> { new UserThingA(), new SystemThingB(), new SystemThingC(), new UserThingC() };
foreach (var thing in mylist)
{
thing.Accept(visitor);
}
}
}
}
Seems like you got it all backwards. First of all, let's talk about the Liskov Substitution Principle. It says that any type should be replaceable by the base type. This also apply to the visitor pattern.
If you have a method called void Accept(IVisitor visitor), it should not matter if a FancyVisitor or a SipleVisitor that is visiting.
The whole idea with the visitor pattern is that the subject (i.e. the class that is being visited) should not know anything about the visitor more than the contract (base class or interface) that it implements. And each Visitor class should be specific for a certain class being visited.
And that's the problem with your code. You are trying to make a general Visitor class that can visit all your system components. That's plain wrong.
As I see it, you have two options:
You want to collect the same kind of information from all system components.
Easy. Create a new interface which all system components implement. Then change the visitor to Visit(ISystemCompoent subject).
You want to collect different kinds of information from each system component
Then you need to create different visitor base classes (or interfaces).
No, it is not possible to mix the visitor pattern with visions of an extensible class hierarchy. They are mutually exclusive.
One solution from this series of blog posts could involve using "interfaces and dynamic type casts to overcome the Visitor pattern’s problems with extensible class hierarchies"
eg:
class UserThingC : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
}
(Not saying this is the best, just an alternative)
Yes, you can do this using reflection. The main idea of using a visitor pattern is for double dispatch. Using reflection you can get all the Visit(...) methods from any visitor and invoke the right method based on the parameter type of the Visit method.
If you go this route, you won't necessarily need an inheritance hierarchy for the visitor or the element you are visiting. In fact, the element classes won't even need to know about the visitor interface (or base class).
To make it clear, below is a code sample that implements a generic visitor that uses reflection to do double dispatch. Using the GenericVisitor<T>::AcceptVisitor(...), you can get any element (derived or not) to call the right method in the any visitor (derived or not) as long as the visitor T defines a method Visit(...) for that particular element class.
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace VisitorPattern
{
class GenericVisitor<T>
{
// Dictionary whose key is the parameter type and value is the MethodInfo for method "Visit(ParameterType)"
static Dictionary<Type, MethodInfo> s_visitorMethodDict;
static GenericVisitor()
{
s_visitorMethodDict = new Dictionary<Type, MethodInfo>();
Type visitorType = typeof(T);
MethodInfo[] visitorMethods = visitorType.GetMethods();
// Loop through all the methods in class T with the name "Visit".
foreach (MethodInfo mi in visitorMethods)
{
if (mi.Name != "Visit")
continue;
// Ignore methods with parameters > 1.
ParameterInfo[] parameters = mi.GetParameters();
if (parameters.Length != 1)
continue;
// Store the method in the dictionary with the parameter type as the key.
ParameterInfo pi = parameters[0];
if (!s_visitorMethodDict.ContainsKey(pi.ParameterType))
s_visitorMethodDict.Add(pi.ParameterType, mi);
}
}
public static bool AcceptVisitor(object element, T visitor)
{
if (element == null || visitor == null)
return false;
Type elementType = element.GetType();
if (!s_visitorMethodDict.ContainsKey(elementType))
return false;
// Get the "Visit" method on the visitor that takes parameter of the elementType
MethodInfo mi = s_visitorMethodDict[elementType];
// Dispatch!
mi.Invoke(visitor, new object[] { element });
return true;
}
}
// Element classes (note: they don't necessarily have to be derived from a base class.)
class A { }
class B { }
class Visitor
{
public void Visit(A a) { System.Console.WriteLine("Visitor: Visited A"); }
public void Visit(B b) { System.Console.WriteLine("Visitor: Visited B"); }
}
interface IVisitor
{
void Visit(A a);
void Visit(B b);
}
class DerivedVisitor : IVisitor
{
public void Visit(A a) { System.Console.WriteLine("DerivedVisitor: Visited A"); }
public void Visit(B b) { System.Console.WriteLine("DerivedVisitor: Visited B"); }
}
class Program
{
static void Main(string[] args)
{
Object a = new A();
Object b = new B();
// Example of Visitor that doesn't use inheritance.
Visitor v1 = new Visitor();
GenericVisitor<Visitor>.AcceptVisitor(a, v1);
GenericVisitor<Visitor>.AcceptVisitor(b, v1);
// Example of Visitor that uses inheritance.
IVisitor v2 = new DerivedVisitor();
GenericVisitor<IVisitor>.AcceptVisitor(a, v2);
GenericVisitor<IVisitor>.AcceptVisitor(b, v2);
}
}
}
You could use the new dynamic keyword like this:
public class Visitable1
{
public void Accept(dynamic visitor)
{
visitor.Visit(this);
}
}
public class DynamicVisitor
{
public void Visit(Visitable1 token)
{
// Call token methods/properties
}
}
However, you expose your code to MissingMethodException
Yes, you can do this.
Change all your UserThing's Accept(SystemVisitor visitor)methods to accept a UserVisitor instead.
Add an abstract base class for all your UserThings
In the abstract base class add an Accept method that attempts to cast the visitor from a SystemVisitor to a UserVisitor. if it succeeds it calls the Accept method on the UserThing.
public override void Accept(SystemVisitor visitor)
{
var visitorAsUser = visitor as UserVisitor;
if (visitorAsUser != null)
return this.Accept(UserVisitor);
}
The SystemVisitor still knows nothing about your UserThings and an existing SystemVisitor cannot visit them, but your UserVisitor can.
I have the following C# test code:
class MyItem
{
MyItem( int a ) {}
}
class MyContainer< T >
where T : MyItem, new()
{
public void CreateItem()
{
T oItem = new T( 10 );
}
}
Visual Studio can't compile it, the error is at line where 'new' is used:
'T': cannot provide arguments when creating an instance of a variable type
Is it possible in C# to create an object of generic type with non-parameterless constructor? It's no problem to do such thing in C++ templates, so i'm very curious why i can't do same thing in C#. Maybe some additional 'where' is required or syntax is different?
C#, and VB.Net for that matter, do not support the notion of constraining a generic to have a constructor with specific parameters. It only supports constraining to have an empty constructor.
One work around is to have the caller pass in a factory lambda to create the value. For instance
public void CreateItem(Func<int,T> del) {
T oItem = del(10);
}
Call site
CreateItem(x => new SomeClass(x));
It can be done with reflection:
public void CreateItem()
{
int constructorparm1 = 10;
T oItem = Activator.CreateInstance(typeof(T), constructorparm1) as T;
}
But there is no generic constraint to ensure that T implements the desired constructor, so I wouldn't advise doing this unless you are careful to declare that constructor in every type that implements the interface.
There's no such generic constraint, so it's not possible directly (this is a CLR limitation). If you want this, you have to provide a factory class (which has a parameterless constructor), and pass it as a second generic type parameter.
IMO, the best approach here is an initialize method, i.e.
interface ISomeInterface {
void Init(int i);
}
class Foo : ISomeInterface {
void ISomeInterface.Init(int i) { /* ... */ }
}
static class Program {
static T Create<T>(int i) where T : class, ISomeInterface, new() {
T t = new T();
t.Init(i);
return t;
}
static void Main() {
Foo foo = Create<Foo>(123);
}
}
However, you can do what you want with Expression (but without compile-time support):
using System;
using System.Linq.Expressions;
class Foo {
public Foo(int i) { /* ... */ }
}
static class Program {
static T Create<T>(int i) {
return CtorCache<T>.Create(i);
}
static class CtorCache<T> {
static Func<int, T> ctor;
public static T Create(int i) {
if (ctor == null) ctor = CreateCtor();
return ctor(i);
}
static Func<int, T> CreateCtor() {
var param = Expression.Parameter(typeof(int), "i");
var ci = typeof(T).GetConstructor(new[] {typeof(int)});
if(ci == null) throw new InvalidOperationException("No such ctor");
var body = Expression.New(ci, param);
return Expression.Lambda<Func<int, T>>(body, param).Compile();
}
}
static void Main() {
Foo foo = Create<Foo>(123);
}
}
Note that this caches and reuses the delegate for performance.
One pattern I use is to have the constrained class implement an interface which defines an Init method with the appropriate signature:
interface IMyItem
{
void Init(int a);
}
class MyItem : IMyItem
{
MyItem() {}
void Init(int a) { }
}
class MyContainer< T >
where T : MyItem, IMyItem, new()
{
public void CreateItem()
{
T oItem = new T();
oItem.Init( 10 );
}
}