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()
Related
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);
}
}
I have a class in which I would like to store a function call. This function call can be invoked by the class but set by the parent class. I would like to externally supply the call to be made, including any parameters.
Something like...
public class TestDelegate
{
public TestDelegate()
{
TestClass tc = new TestClass(DoSomething("blabla", 123, null));
}
private void DoSomething(string aString, int anInt, object somethingElse)
{
...
}
}
public class TestClass
{
public TestClass(delegate method)
{
this.MethodToCall = method;
this.MethodToCall.Execute();
}
public delegate MethodToCall { get; set; }
}
When the TestClass class is initialized it will call the DoSomething method of the parent class with the specified parameters. I should also mention that I do not want to require the same method signature for the method called. Meaning not always (string, int, object)
Use the Action delegate type and create an instance of this from a closure:
public class TestClass
{
public TestClass(Action method)
{
MethodToCall = method;
method();
}
public Action MethodToCall { get; set; }
}
public class TestDelegate
{
public TestDelegate()
{
// Uses lambda syntax to create a closure that will be represented in
// a delegate object and passed to the TestClass constructor.
TestClass tc = new TestClass(() => DoSomething("blabla", 123, null));
}
private void DoSomething(string aString, int anInt, object somethingElse)
{
// ...
}
}
delegate isn't the name of a type - it's a keyword used to declare delegate types, and also anonymous methods.
I suspect you actually want a specific type of delegate, such as Action, which is a delegate with no parameters and a void return type. You'll then need to change your calling code as well - because currently you're calling DoSomething before you call the constructor. Sample:
public class TestDelegate
{
public TestDelegate()
{
TestClass tc = new TestClass(() => DoSomething("blabla", 123, null));
}
private void DoSomething(string aString, int anInt, object somethingElse)
{
...
}
}
public class TestClass
{
public TestClass(Action method)
{
this.MethodToCall = method;
this.MethodToCall.Invoke();
}
// Do you really need this to be writable?
public Action MethodToCall { get; set; }
}
So I have an interface called IWorkItem that is implemented in WorkA, WorkB and many other classes.
public interface IWorker<T> where T : IWorkItem
{
void Process(T item);
}
The IWorker<T> interface is implemented in WorkerA (IWorker<WorkA>), WorkerB (IWorker<WorkB>) and many other classes.
public static void ProcessWorkItem(IWorkItem item)
{
(/* find the right worker */).Process(item);
}
Now my problem is: How do find a worker object that is able to process the given IWorkItem?
My first attempts look like this, but the generic type arguments are a problem:
public static class WorkerRepository
{
private static Dictionary<Type, IWorker<???>> RegisteredWorkers =
new Dictionary<Type, IWorker<???>>();
public static void RegisterWorker(IWorker<???> worker)
{
var handled = from iface in worker.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(IWorker<>)
select iface.GetGenericArguments()[0];
foreach (var type in handled)
if (!RegisteredWorkers.ContainsKey(type))
RegisteredWorkers[type] = worker;
}
public static void ProcessWorkItem(IWorkItem item)
{
RegisteredWorkers[item.getType()].Process(item);
}
}
So I have the Dictionary that contains the workers. Which type argument do I need here? In Java I could just use ? extends IWorkItem, but do I do that in C#?
Then there is RegisterWorker. You would probably suggest a generic type argument for the entire method, like RegisterWorker<T>(IWorker<T> worker). However, that also won't work, since I would like to dynamically load, instantiate and register Workers.
Is this even the right approach or is there a better way to accomplish this?
I made a few changes but got a solution where you can keep things generic (instead of using objects). Not sure if you even care, but thought to add it as answer and let you decide.
I also wrote a test to check if it actually works, you should be able to copy/paste it.
[TestFixture]
public class WorkerThing
{
[Test]
public void RegisterAndRetrieveWorkers()
{
var repo = new WorkerRepository();
repo.RegisterWorker(new WorkerA());
var workerA = repo.RetrieveWorkerForWorkItem(new WorkItemA());
Assert.IsTrue(workerA is WorkerA);
repo.RegisterWorker(new WorkerB());
var workerB = repo.RetrieveWorkerForWorkItem(new WorkItemB());
Assert.IsTrue(workerB is WorkerB);
}
}
The WorkerRepository class.
public class WorkerRepository
{
private readonly Dictionary<Type, IWorker<IWorkItem>> _registeredWorkers =
new Dictionary<Type, IWorker<IWorkItem>>();
public void RegisterWorker(IWorker<IWorkItem> worker)
{
var type = (from iface in worker.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(IWorker<>)
select iface.GetGenericArguments()[0]).First();
if (!_registeredWorkers.ContainsKey(type))
{
_registeredWorkers[type] = worker;
}
}
// You don't need this method, just added it to check if I indeed retrieved the correct type
//
public IWorker<IWorkItem> RetrieveWorkerForWorkItem(IWorkItem item)
{
var type = item.GetType();
var registeredWorker = _registeredWorkers[type];
return registeredWorker;
}
public void ProcessWorkItem(IWorkItem item)
{
var type = item.GetType();
var registeredWorker = _registeredWorkers[type];
registeredWorker.Process(item);
}
}
The work item interfaces & classes.
public interface IWorkItem
{
}
public class WorkItemA : IWorkItem
{
}
public class WorkItemB : IWorkItem
{
}
And here I added the out keyword to allow covariance typing on the interface. That way you can convert WorkerA to IWorker<IWorkItem>. (as in the unit test example)
public interface IWorker<out T> where T : IWorkItem
{
void Process(IWorkItem workItem);
}
public class WorkerA : IWorker<WorkItemA>
{
public void Process(IWorkItem item)
{
}
}
public class WorkerB : IWorker<WorkItemB>
{
public void Process(IWorkItem item)
{
}
}
No object dictionaries. No reflection. I hope the example is useful!
Cheers (and thx for the cool question, it kept me busy for a while :))
It looks like you want something like this:
private static Dictionary<Type, object> RegisteredWorkers = new Dictionary<Type, object>();
public static void RegisterWorker(object worker)
{
var handled = from iface in worker.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(Worker<>)
select iface.GetGenericArguments()[0];
foreach (var type in handled)
if (!RegisteredWorkers.ContainsKey(type))
RegisteredWorkers[type] = worker;
}
public static void ProcessWorkItem(WorkItem item)
{
object handler = RegisteredWorkers[item.getType()];
Type workerType = typeof(Worker<>).MakeGenericType(item.GetType());
MethodInfo processMethod = workerType.GetMethod("Process");
processMethod.Invoke(handler, new object[] { item });
}
If you don't want to invoke the handlers through reflection each time you can generate an Action<IWorkItem> handler when you register the handler:
public void RegisterHandler(object handler)
{
var handled = from iface in handler.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(IWorker<>)
select iface.GetGenericArguments()[0];
foreach (var type in handled)
{
if (!RegisteredWorkers.ContainsKey(type))
{
Action<IWorkItem> handleAction = HandlerAction(type, handler);
RegisteredWorkers[type] = handleAction;
}
}
}
public void Process(IWorkItem item)
{
Action<IWorkItem> handleAction = RegisteredWorkers[item.GetType()];
handleAction(item);
}
private static Action<IWorkItem> HandlerAction(Type itemType, object handler)
{
var paramExpr = Expression.Parameter(typeof(IWorkItem));
var castExpr = Expression.Convert(paramExpr, itemType);
MethodInfo processMethod = typeof(IWorker<>).MakeGenericType(itemType).GetMethod("Process");
var invokeExpr = Expression.Call(Expression.Constant(handler), processMethod, castExpr);
var lambda = Expression.Lambda<Action<IWorkItem>>(invokeExpr, paramExpr);
return lambda.Compile();
}
How to call protected constructor?
public class Foo{
public Foo(a lot of arguments){}
protected Foo(){}
}
var foo=???
This obviously fails test:
public class FooMock:Foo{}
var foo=new FooMock();
Assert(typeof(Foo), foo.GetType());
Call parameterless protected/private constructor:
Foo foo = (Foo)Activator.CreateInstance(typeof(Foo), true);
Call non-public constructor with parameters:
var foo = (Foo)typeof(Foo)
.GetConstructor(
BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance,
null,
new[] { typeof(double) },
null
)
.Invoke(new object[] { 1.0 });
class Foo
{
private Foo(double x){...}
}
You can only call that from a subclass, basically. Your FooMock class will already be calling the protected constructor, because it's equivalent to:
public class FooMock : Foo
{
public FooMock() : base() // Call the protected base constructor
{
}
}
However, your assertion will fail because the type of object referred to be foo is FooMock, not Foo.
An assertion of the form foo is Foo will pass though.
You can't construct an instance of just Foo by calling the protected constructor directly. The point of it being protected instead of public is to ensure that it's only called by subclasses (or within the text of Foo itself).
It's possible that you could call it with reflection within a full trust context, but I'd urge you not to do so.
The only way to cause a protected constructor to be called is to derive from the class and have the derived class delegate to it or to have a static method create it or some other internal method.
EDIT: What the Skeet said!
You cannot call a protected method - although you can call an internal one (using InternalsVisibleTo attribute). You need to expose it in a different way.
Serj-Tm answered adequately but Activator can do it too:
var foo = (Foo) Activator.CreateInstance(typeof(Foo),
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { 2.0 },
CultureInfo.InvariantCulture);
If you want to avoid repeated reflection cost, you can use expressions.
Here is an example of calling a private constructor with a string value.
private static Func<string, T> CreateInstanceFunc()
{
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
var ctor = typeof(T).GetConstructors(flags).Single(
ctors =>
{
var parameters = ctors.GetParameters();
return parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
});
var value = Expression.Parameter(typeof(string), "value");
var body = Expression.New(ctor, value);
var lambda = Expression.Lambda<Func<string, T>>(body, value);
return lambda.Compile();
}
Save the cost of compiling the function multiple times by storing it in a static field.
private static readonly Lazy<Func<string, T>> CreateInstance = new Lazy<Func<string, T>>(CreateInstanceFunc);
Now you can create the object with
CreateInstance.Value("Hello")
If you need to explicitly call the constructor of you base class in your subclass, you have to use the keyword base
may be this will help:
abstract parent class:
public abstract class Animal
{
private string name;
public Animal(string name)
{
this.Name = name;
}
public Animal() { }
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public virtual void talk()
{
Console.WriteLine("Hi,I am an animal");
}
}
class with protected constructor:
public class Lion : Animal
{
private string yahoo;
protected Lion(string name) : base(name)
{
this.Yahoo = "Yahoo!!!";
}
public string Yahoo
{
get
{
return yahoo;
}
set
{
yahoo = value;
}
}
public Lion() { }
}
class Kiara derived from Lion class :
public class Kiara : Lion
{
public Kiara(string name) : base(name)
{
}
public override void talk()
{
Console.WriteLine("HRRRR I'm a Kiara");
}
public Kiara() { }
}
class Simba derived from Lion class :
public class Simba : Lion
{
public Simba(string name) : base(name)
{
}
public override void talk()
{
Console.WriteLine("HRRRR I'm a {0} and this is my daughter:{1} {2}",
new Simba("Simba").Name,
new Kiara("Kiara").Name,
new Simba("Simba").Yahoo);
}
public Simba() { }
}
implementation in main function:
public static void Main(string[] args)
{
Animal lion = new Simba();
lion.Name = "Simba";
lion.talk();
Animal lion1 = new Kiara();
lion1.Name = "Kiara";
lion1.talk();
}
Is there any way to override a class method with a lambda function?
For example with a class definition of
class MyClass {
public virtual void MyMethod(int x) {
throw new NotImplementedException();
}
}
Is there anyway to do:
MyClass myObj = new MyClass();
myObj.MyMethod = (x) => { Console.WriteLine(x); };
Chris is right that methods cannot be used like variables. However, you could do something like this:
class MyClass {
public Action<int> MyAction = x => { throw new NotImplementedException() };
}
To allow the action to be overridden:
MyClass myObj = new MyClass();
myObj.MyAction = (x) => { Console.WriteLine(x); };
No. However if you declare the method as a lambda in the first place, you can set it, though I would try to do that at initialization time.
class MyClass {
public MyClass(Action<int> myMethod)
{
this.MyMethod = myMethod ?? x => { };
}
public readonly Action<int> MyMethod;
}
This however cannot implement an interface that has a MyMethod declared, unless the interface specifies a lambda property.
F# has object expressions, which allow you to compose an object out of lambdas. I hope at some point this is part of c#.
No. Methods cannot be used like variables.
If you were using JavaScript, then yes, you could do that.
You can write this code:
MyClass myObj = new MyClass();
myObj.TheAction = x => Console.WriteLine(x);
myObj.DoAction(3);
If you define MyClass in this way:
class MyClass
{
public Action<int> TheAction {get;set;}
public void DoAction(int x)
{
if (TheAction != null)
{
TheAction(x);
}
}
}
But that shouldn't be too surprising.
Not directly, but with a little code it's doable.
public class MyBase
{
public virtual int Convert(string s)
{
return System.Convert.ToInt32(s);
}
}
public class Derived : MyBase
{
public Func<string, int> ConvertFunc { get; set; }
public override int Convert(string s)
{
if (ConvertFunc != null)
return ConvertFunc(s);
return base.Convert(s);
}
}
then you could have code
Derived d = new Derived();
int resultBase = d.Convert("1234");
d.ConvertFunc = (o) => { return -1 * Convert.ToInt32(o); };
int resultCustom = d.Convert("1234");
Depending on what you want to do, there are many ways to solve this problem.
A good starting point is to make a delegate (e.g. Action) property that is gettable and settable. You can then have a method which delegates to that action property, or simply call it directly in client code. This opens up a lot of other options, such as making the action property private settable (perhaps providing a constructor to set it), etc.
E.g.
class Program
{
static void Main(string[] args)
{
Foo myfoo = new Foo();
myfoo.MethodCall();
myfoo.DelegateAction = () => Console.WriteLine("Do something.");
myfoo.MethodCall();
myfoo.DelegateAction();
}
}
public class Foo
{
public void MethodCall()
{
if (this.DelegateAction != null)
{
this.DelegateAction();
}
}
public Action DelegateAction { get; set; }
}