I have a base class, whose ctor takes a delegate as a parameter and a class which inherits from it.
The following works just fine:
class Base
{
public Base(Func<bool> func)
{
}
}
class Sub : Base
{
public Sub()
: base(() => true)
{
}
public Sub(int i)
: base(() => { return true; })
{
}
}
How can I pass an instance function as a parameter?
Compiler complains with error "An object reference is required for the non-static field, method, or property".
What I would like to have is this:
class Sub : Base
{
public Sub()
: base(Func)
{
}
private bool Func()
{
return true;
}
}
It would work if Func was a static method. But I'd like to use instance members inside the function.
How could I accomplish this?
As commented this looks to me like an X Y problem to me, and seems like a flawed design,
can you change your base class to just call a virtual method and just override it ?
class Base
{
public Base()
{
}
public virtual bool func() {return false};
}
class Sub : Base
{
public Sub()
{
}
public override bool func()
{
return true;
}
}
also you can read more about it at https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/virtual
Related
I have a child class that does not override one of it's parent's base methods. I want to create that override at runtime. Can I do that? I know it's possible to modify a method that already exists, but this is slightly different.
Suppose I have:
class MyBaseClass
{
public bool testMethod() {
return false;
}
}
class MyChildClass : MyBaseClass
{
}
...
MyBaseClass p=new MyBaseClas();
MyChildClass child=new MyChildClass();
p.testMethod(); // should always return false
child.testMethod(); // returns false
.... // Do Magic?
// Make child.testMethod(); return true
If MyChildClass had created an override of testMethod(), I could use Reflection;
// If
class MyChildClass : MyBaseClass
{
public override bool testMethod() {
return false;
}
}
// then I could have
MethodInfo m = typeof(MyChildClass).GetMethod("testMethod");
// and then do reflection stuff to change it
But m is null.
Can I make it so whenever a MyChildClass instance calls testMethod(), it returns true?
To modify the behavior of a derived class at runtime you should build that in as a feature of the class:
class MyBaseClass
{
public virtual bool TestMethod() => false; // MUST BE VIRTUAL
}
class MyChildClass : MyBaseClass
{
public MyChildClass()
{
implementation = () => base.TestMethod();
}
private Func<bool> implementation = null;
public override bool TestMethod() => this.implementation();
public void SetImplementation(Func<bool> f) => this.implementation = f;
}
And now you can make a new MyChildClass and call SetImplementation(()=>true); to change the behaviour of the class.
public class Test<T>
{
private T something;
public Test<NewT> Cast<NewT>() where T : NewT
{
return new Test<NewT>() { something = this.something };
}
}
VS Error: 'Test.Cast()' does not define type parameter 'T'
Why does this happens?
This is because you can only constrain type parameters that are defined in the method. T is not defined in the method, but in the class, so you can't constrain it like that.
You can, however, make Cast an extension method:
// in some static class
public static Test<NewT> Cast<T, NewT>(this Test<T> test) where T : NewT {
return new Test<NewT>() { something = test.something };
}
This means that something has to be made public, which can sometimes be undesirable. You can alternatively do something like this:
public class Test<T>
{
public T Something { get; private set; }
public Test(T something) {
Something = something;
}
}
// in some static class
public static Test<NewT> Cast<T, NewT>(this Test<T> test) where T : NewT
{
return new Test<NewT>(test.Something);
}
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; }
}
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();
}