preventing sub class methods to run from base class constructor - c#

The question title seems a little bit odd doesn't it. Anyway. So I have one base class which has some private fields, protected properties and a single constructor that takes one argument and I have several sub classes of that base class. whenever any of those subclass methods are called the sub classes are required to be instantiated and after the method is done executed the object is destroyed so if the method will be called again new instance of the class should be made. (Its a WCF service) Now, the thing I want to do is the following. whenever the certain sub class constructor is called I call the base class constructor explicitly with some certain parameter (different for every sub class, Note: no sub class methods are the same), When the base class constructor is called I want to check something according to that argument and if it passes the check then I want to allow the execution of sub class method. In any other case I want it NOT to run the sub class method. So I want something like this. when the method is called the sub class has to be constructed and for that, base class has to be constructed as well and if the check fails in the base class' constructor I want to prevent that method from running. I can just have a bool property and set it in base class' constructor and check it on every method call. but I want to make something more general. May be the way that I'm suggesting Is not right either. So you understand what I want I guess. Any suggestion would be appriciated. thanks in advance
class BaseClass
{
private bool _isValid;
private SomeService someService;
public BaseClass(SomeEnum value)
{
someService = new SomeService();
if (someService.Validate(value))
{
_isValid = true;
}
}
protected internal bool IsValid { get { return _isValid; } }
}
class SubClass : BaseClass
{
// object declaration
public SubClass () : base(SomeEnum.SomeValue)
{
// constructing some objects here
}
public Response Operation('parametereGoHere')
{
if (IsValid)
{
// perform operation. construct Response object and return it
}
}
// other methods omitted.
}
So whenever the Operation() method is called SubClass has to be constructed which causes the BaseClass to be constructed and the base class sets the value of _isValid which is then use to check for validity, but I wanted to make something more general. lets that instead of just setting the value of _isValid to true just do nothing or set some other properties and if the Valiate() failed just stop the execution and don't to anything at all. In this case the calling routing wouldn't be able to call Operation() if we somehow managed to stop the construction of class. If it's not possible I'm perfectly happy with the solution I have right now. But if it is I will be glad to see that. Note: In every sub class, methods are different and I have to check IsValid to allow the execution of method.

You should be able to use the out parameter to get the constructor to return a value.

Very hard to follow what you want, but it sounds like you want a case where the base constructor doesn't do anything sometimes. Then simply make a base constructor that doesn't do anything, and call it (with the : base() call). Use a dummy argument if necessary.
class A {
public A() { a= 1; }
public A(double dummy); { }
}
class B
public B() : base() { // calls the base constructor that does something
}
public B(int) : base(1.0) {// class the base construct that does nothing
}
}

Related

How to initialize static fields in subclasses

I have an abstract base class, and subclasses who all have an automatically generated Instance static field of their own type, done through using genericity "in between" the base and sub classes (see code below).
When those instances are created, I register them in a dictionary based on specific "identifying" fields overwritten in subclass constructors, in order to access them somewhere else in the code.
I could register them in their constructors, however I don't want to have to drag and copy/paste this same bit of code in every such subclass in order to register them.
public abstract class BaseClass
{
// Declaration of fields and methods
}
public class GenericBaseClass<T> : BaseClass where T : GenericBaseClass<T>
{
private static T instance = ((T) Activator.CreateInstance(typeof(T), true)).Register();
public static T Instance => instance;
public T Register()
{
// Registers Instance in a dictionary.
}
}
public class Subclass1 : GenericBaseClass<Subclass1>
{
private Subclass1()
{
// Modification of protected fields.
}
}
Doing this enables me to call Subclass1.Instance, and by doing so, this instance gets registered in my dictionary, however it doesn't get registered before I try to access it, and only Subclass1 gets that treatment, not other subclasses.
I followed this answer https://stackoverflow.com/a/34726769/13738641 (in the updated section) and made a static constructor for BaseClass and for GenericBaseClass hoping it would initialize static fields for those subclasses, to no avail.
It appears from debugging that the BaseClass static constructor is indeed called, and it does fetch the right subclasses, but it doesn't throw an error, nor does it calls the subclass (static) constructors. Now I could be going crazy, but I could have sworn it worked once before I tried modifying something before reverting back to that, only for it not to work anymore.
I've tried adding a static constructor to the generic class which I hoped would be called once for each subclass, but this constructor only gets called once (when I access some subclass's instance in order to trigger the BaseClass static constructor call).
Any suggestion on what to do to achieve this? I accept suggestion on other ways to achieve something similar (i.e. keep a dictionary generated at runtime with instances of my classes), the subclasses being singletons isn't critical, so maybe I could register constructors instead of instances in the dictionary? I have no idea if that is even possible, with each constructor returning a different type.
You could loop through the types in your assembly and check if they implement the generic class, and then invoke the static constructor of the generic class (which will implicitly invoke the static constructor of the sub class because of Activator.CreateInstance) by calling RuntimeHelpers.RunClassConstructor. So just add a method that does that can call it:
public static void RegisterAll()
{
foreach(var type in typeof(BaseClass).Assembly.GetTypes().Where(t => t.BaseType.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(GenericBaseClass<>)))
{
RuntimeHelpers.RunClassConstructor(type.BaseType.TypeHandle);
}
}

Passing information between two class with one being MonoBehavior

I want to pass data from classA to classB that extends MonoBehavior.
I created a method called activate as follows in my classB
public void activate(String nameVal)
{
}
I called the above method using ClassB.activate("data"). but for some reason, it is never being called. How do I send a callback from classA to classB?
Depending on your needs :
1) Make the activate() static. Just as in C#, you don't need reference to the object to call a static method.
2) If you fit the "one-object" requirement, you can use the Singleton Pattern.
There are quite a few tuto about it over the internet, so i won't extend on it too much but basically, you create a static variable containing your unique object, like this :
public class Singleton : MonoBehaviour
{
private static Singleton instance = null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
You can have an idea of more advanced way to implement it in this tutorial.
EDIT :
It should be noted that it's quite a strange needs. Usually, it's the monobehaviours that control the other "simple" script. You may indeed need a callback, after a process in a non-monobehaviour, but in this case, the Script B has the references to classA.
So i add a 3) a proper callback :
class B, containing MyCallback() (a proper method fitting the needs).
myObjectA.DoSomeProcess("data", MyCallback);
class A:
public void DoSomeProcess(string data, Action<string> callback)
{
// Some process
callback("data processed");
}
It depends on the method on classA.
CallClassB is not called.
If you're calling CallClassB(), then you can be fully sure that either ClassB.activate("data"); will be called or you get a NullReference Exception.
public class classA
{
public classB ClassB;
//this method either:
//OPTION 1 - calls ClassB.activate
//OPTION 2 - gets a NullReference Exception
public void CallClassB()
{
ClassB.activate("data");
}
}
FURTHER NOTE:
It might be worth considering that in C# lowerCamelCase represents variables (as instances of a class), while UpperCamelCase is for Class.
Reading your comment it seems you're doing the opposite.
FURTHER NOTE 2:
This is not a callback. If we're talking about a callback we should mention events, listeners, delegates or any other possible callback. If this is your case the answer is:
- Your callback has not been received by classB.
Why depends on the callback not on the Method.

How can I set derived static members before calling static functions of the base class

I have the following class:
class Base<T> where T : Base<T>
{
protected static string Source;
public static List<T> Read()
{
return GetResource(Source);
}
}
I want this class as baseclass for its functionality but every derived class has to have a different Source. My problem is that I can't assure the Source is set before Read is called. I know I could ask if the Source is set before GetResource is called but that's not the point. I need it to be set before any static member of my class is called.
Generic parameters can't have static Members so I can't take it from there.
I tried setting the Source in the derived class's static constructor but that will only be called when I call a member that is in the derived class and not in the Base.
I tried using a overridable method inside of the static Base constructor but such a method has to be static as well and static methods can't be overwritten.
When I set the Source manually, there is a chance that the Read-Function has already been called, so I have to set the Source before it can be called.
I know I could give Source as a parameter in Read but I want Read to be used without parameters.
Is there any way I can assure that the Source is Set before any other Member of my class is called, so that any dependent code is inside the derived class and doesn't have to be called by anyone using a derived class?
I basically want it to work like this:
class Derived : Base<Derived>
{
// somehow set Source
Source = "This is my source";
}
class User
{
private List<Derived> MyResources;
public User()
{
MyResources = Derived.Read();
}
}
Note: the Source is basically a SQL statement so an Attribute or something like that wont be sufficient I think.
Ok, I found an answer. It is not as pretty as I hoped it would be but its the best I could come up with.
I will use an interface to force an Instance of T to have a certain method that provides my source.
interface ISource
{
string GetSource();
}
I then implement that into my base class as such:
class Base<T> where T : Base<T>, ISource, new()
{
public static List<T> Read()
{
// here I create an Instance to be able to call the Methods of T
string source = (new T()).GetSource();
return GetResource(source);
}
}
The derived class:
class Derived : Base<Derived>, ISource
{
public string GetSource()
{
return "This specific source";
}
}
Usage as such:
class User
{
public User()
{
List<Derived> myResources = Derived.Read();
}
}
This of course will lead to every instance of Derived having the GetSource-method but for my scenario thats not a big deal.
Also, since it creates an instance in the Read-method, this could be time consuming depending on the constructor of Derived. In my scenario it only has the standard constructor.
So use with caution.

automatic post-construction initialisation

virtual methods should not be called in the constructor of a base class because the constructor of the derived class is not called and so all initialisation logic isn't invoked.
I want to know if there is a way to hook in there to automatically call a method after the object is completely constructed.
I do not want to push the responsibility of calling an initialise method onto the user.
Lets say I have the following
public abstract class Foo
{
protected Foo()
{
...
AfterConstruction();
}
protected virtual void AfterConstruction(){}
}
public class Bar : Foo
{
protected override void AfterConstruction()
{
...
}
}
I know this should not be done and I thought maybe one can get around this by using reflection to observe object construction and then hook after the construction is finished to call the function AfterConstruction().
But I cannot find appropriate code to do so.
Thank you for your thoughts
If I miss some important detail, do tell, but you have multiple options depending on when your class is considered fully initialized.
Also, "After Constructor" is the same as last line inside constructor (usually anyways), is there anything inside your logic to contradict that?
If full class initialization can be achieved inside the class you are making:
1. Call it at the end of constructor or wherever your class is initialized.
2. Call it in child class after base constructor. This will ensure base class is initialized.
If you cannot achieve a full class initialization inside your own classes, in other words, if your class is only considered initialized AFTER the user initialized some parameters - you have no choice but to leave at least 1 method call to the creator of your child class.
Default constructor of a base class will be called before child class constructor:
Simple code to test:
class Program
{
static void Main(string[] args)
{
new Bar();
}
}
class Foo
{
public Foo()
{
MessageBox.Show("Foo");
}
}
class Bar : Foo
{
public Bar()
{
MessageBox.Show("Bar");
}
}
Output:
MessageBox: "Foo"
MessageBox: "Bar"

this or base? In which case could we use base instead of this?

In the following code
// MVVM Views part class
public partial class DashBoard : UserControl
{
public DashBoard()
{
InitializeComponent();
this.DataContext = new DashBoardViewModel();
}
}
Could we use base.DataContext instead this.DataContext. In which case could we use base instead of this?
It's usually clearer to use this. You normally only specify base when you want to explicitly call a base class constructor or the base implementation of an overridden method or property.
Using base.DataContext would work, but it would might imply that this.DataContext would mean something different.
You use this to access a method defined in the present class (or superclass if it's not in the present class). You use base to access a method in the superclass or higher. In this case you could have used either (or none as Marc points out above).
I prefer to emit this except when it's (rarely) required.
To add to what the others have said, base. is used when you've overridden something from the base class with either the overrides or new keywords, you'll need to use base to gain access to the original method.
class a
{
public virtual void method1()
{
}
public string property1 { get; set; }
}
class b : a
{
// this has it's own instance in b, the only way to get to
// the original property1 is with base (or reflection)
public new string property1 { get; set; }
public override void method1()
{
// the only way to get to the original method1 and property1
base.method1();
base.property1 = "string";
}
}
In your example if the DataContext property uses either of these keywords then base and this don't mean the same thing at all.
Considering your case u are trying to initialize DataContext property of class DashBoard with some value. So if you then call DataContext typed property of (base)UserControl class object, it still will be not initialized. Therefore, to decide which property to initialize, u must to look to your program's logic.
Basicly MSDN tells that u should use (base.) in two scenarious:
-Call a method on the base class that has been overridden by another method.
-Specify which base-class constructor should be called when creating instances of the derived class.
In my practise i used first scenario when (this) method ends with exception, i was trying to call more general (base) method. Good luck!

Categories

Resources