How to call protected constructor in c#? - c#

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();
}

Related

How do you create a delegate based on a lambda using reflection?

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()

C# Get type of subClass and create object of this

class MainClass {
private int someMethod() {
IList <SubClass> obj = db.Query <SubClass> (delegate(SubClass obj) {
return obj.Points == 100;
});
}
}
class SubClass : MainClass {
public int someField;
}
SubClass obj = new SubClass();
obj.someMethod();
SubClasses can be differnt, i need get instance of this for make a query to db4o.
Evaluating subclass types from base class to make some processing, is generally a bad decision, consider adding a composed method to the base class, then leverage specialized processing to its subclass:
class MainClass {
public string ComposedMethod(){
//Base class processing...
var retVal = someMethod();
//Even more Base class processing...
return retVal;
}
public virtual string someMethod(){
}
}
class SubClass : MainClass {
public override string someMethod(){
return this.GetType().ToString(); //Or whatever you need to do
}
}
Usage:
SubClass obj = new SubClass();
obj.ComposedMethod();

pass callback to class

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; }
}

C# - How can I have an type that references any object which implements a set of Interfaces?

How can I have a type reference that refers to any object that implements a set of interfaces?
For example, I can have a generic type like this:
Java:
public class Foo<T extends A & B> { }
C#
public class Foo<T> where T : A, B { }
That's how to have a class-wide generic type. However, I'd like to simply have a data member which references any object that extends a given set of interfaces.
Example:
public class Foo
{
protected <? extends A, B> object;
public void setObject(<? extends A, B> object)
{
this.object = object;
}
}
If it's possible to have this sort of type syntax, how could I do it in both Java and C#?
I realize I can just create another interface that extends all desired interfaces. However, I don't see this as optimal, as it needlessly adds another type whose sole purpose is to get around syntax. Granted this is a very minor issue, but in terms of elegance it's a bit galling.
My Java has become a bit rusty through 2years of inactivity.
Here's my C# approach: (see https://ideone.com/N20xU for full working sample)
public class Foo
{
private IInterface1 _object; // just pick one
public void setObject<T>(T obj)
where T : IInterface1, IComparable<T>, IEtcetera
{
// you now *know* that object supports all the interfaces
// you don't need the compiler to remind you
_object = obj;
}
public void ExerciseObject()
{
// completely safe due to the constraints on setObject<T>
IEtcetera itf = (IEtcetera) _object;
// ....
}
As far as I know, You cannot create a variable with constraints on it, you can only create a variable of a given type. The type has the constraints. This means you have to define a type that has the constraints you desire, then create the variable with that type.
This seems logical to me, and I don't see why you find it "galling" to have to define a type for what you need.
In C#, you can use a tuple to store the value in a kind of superposition:
public class Foo {
private Tuple<IA, IB> junction;
public void SetValue<T>(T value) where T : IA, IB {
junction = Tuple.Create<IA, IB>(value, value);
}
}
You can also have a specialized class to enforce the constraint that both values reference the same object:
public class Junction {
public IA A { get; private set; }
public IB B { get; private set; }
private Junction() { }
public static Junction Create<T>(T value) where T: IA, IB {
return new Junction {
A = value,
B = value
};
}
}
public class Foo {
private Junction junction;
public void SetValue<T>(T value) where T : IA, IB {
junction = Junction.Create(value);
}
}
In Java, a wildcard would simplify things a little:
class Junction<E extends A & B> {
private final E value;
public Junction(E value) {
this.value = value;
}
public E getValue() {
return value;
}
}
class Foo {
private Junction<?> junction;
public <E extends A & B> void setValue(E value) {
junction = new Junction<E>(value);
}
}
Or you can have aliases to the same value (C#, but also applicable to Java):
public class Foo {
private IA a;
private IB b;
public void SetValue<T>(T value) where T : IA, IB {
a = value;
b = value;
}
}
I don't see any problem with simply stating the constraints as a private interface:
class Foo
{
interface R : I1, I2 { }
R _object;
void setObject(R r) { _object = r; }
}
Here's the best I could come up with (but still not an optimal solution)
public class Foo
{
private TypeWrapper<IInterface1,IInterface2> _object;
public void setObject<T>(T obj)
where T : IInterface1, IInterface2
{
_object = new TypeWrapper<IInterface1, IInterface2>();
_object.SetObject(obj);
var val = _object.Get(h => h.c);
Console.WriteLine(val);
_object.Do(h => h.c = 25);
val = _object.Get(h => h.c);
Console.WriteLine(val);
_object.Do(h => h.someF());
}
}
public class TypeWrapper<TType, TTypeTwo>
{
private Object m_Obj;
public void SetObject<T>(T obj) where T : TType, TTypeTwo
{
m_Obj = obj;
}
public T Get<T>(Func<TType, T> action)
{
return (T)action((TType)m_Obj);
}
public T Get<T>(Func<TTypeTwo, T> action)
{
return (T)action((TTypeTwo)m_Obj);
}
public void Do(Action<TTypeTwo> action)
{
action((TTypeTwo)m_Obj);
}
public void Do(Action<TType> action)
{
action((TType)m_Obj);
}
}
public class myClass : IInterface1, IInterface2 {
public int t {get;set;}
public int c {get;set;}
public void someF() { Console.WriteLine("Fired"); }
}
public interface IInterface1 {
int t { get;set;}
void someF();
}
public interface IInterface2 {
int c { get;set; }
}
You're going to have to work on the object through the Get and Do methods, but it'll work with intellisense and throw compile time errors if the interfaces change.

Can a method be overriden with a lambda function

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; }
}

Categories

Resources