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.
Related
A Quick Note
The code in this post is built on top of a in-house built DirectX-11 engine which means it follows the strict pattern of:
Initialize
while (Running) {
Update
Render
}
However, do not let this deter you as the problem is not related to the DirectX code but instead static classes and methods.
Overview
I have a class called RenderObject which contains a method called Initialize. This method is responsible for building the object's mesh, assigning textures, shaders, and more.
public class RenderObject {
public virtual void Initialize() { }
}
I also have a few static classes that hold reusable assets such as common textures, shaders, models, and meshes. This way I don't have to reload them later. All of these static classes also contain a method called Initialize which is responsible for creating these reusable assets. For this question I will limit this to just the Textures class.
public static class Textures {
public static Texture2D Dirt { get; private set; }
public static Texture2D Grass { get; private set; }
public static void Initialize() {
Dirt = new Texture2D(...);
Grass = new Texture2D(...);
}
}
Finally, I have a class called LoadingSystem which is responsible for loading reusable assets and initializing objects. I initialize this class inside of the Initialize method of my engine, and then call the class' Update method in the Update method of the engine respectively. The LoadingSystem's Update method is responsible for loading and initializing objects using a Queue which is useful for supplying smooth visual feedback.
public class LoadingSystem {
public bool Loading { get; private set; } = true;
private Queue<RenderObject> objectsToRender;
public void AddForLoad(RenderObject obj) => objectsToRender.Enqueue(obj);
public void Update() {
if (objectsToRender.Count > 0) {
RenderObject obj = objectsToLoad.Dequeue();
obj.Initialize();
} else Loading = false;
}
}
The Problem
I would like to call the method Initialize on these static classes with the same process used for the RenderObject queue. Currently I'm forced to do:
CurrentMessage = "Loading Textures";
Render();
Present();
Textures.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Shaders";
Render();
Present();
Shaders.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Models";
Render();
Present();
Models.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
I've slimmed it down to a method that handles the repetitive setting of the message, and calls to Render and Present but this is still tedious and it should go through the Update method once per object to remain consistent with the rest of the code.
My Thoughts
I understand that a static class cannot inherit from a class or implement an interface so I am wondering if there is a way to provide a static class and call its Initialize method in a similar manner; even if this means creating a separate method to accomplish it.
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
The problem with the first option is that I have 12 static classes and would have to update progress and feedback messages, raise events, and re-render the scene for each one.
The problem with the second option is that these static classes only contain static properties and thus by definition should be static as there is no need to ever inherit from them or create an instance of them.
The Question
Is there a way to call a common method across multiple static classes?
Perhaps a way to call the method if it exists with generic types like object or T?
Perhaps the dynamic type may work (though you can't create an instance of static classes)?
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
A third compromise approach relates to your second idea above, but uses a design pattern known as the Singleton Pattern. Like static classes, there can only be one of them in your process and everyone gets that same thing, however unlike static classes, Singletons can implement interfaces or even descend from other classes.
For this example, I will use the interface approach.
public interface IInitializable
{
void Initialize();
}
All the interface does is to enforce that its implementer has an Initialize method.
My next step is to create a Singleton class. There are a couple of rules to implement the Singleton pattern. Your class must be sealed. Its constructor must be private. It must have a static method or property to return the single instance. That method/property must be threadsafe.
I have used Lazy to do the heavy lifting for me
public sealed class Foo : IInitializable
{
public void Initialize()
{
// Initialize my foo
}
private Foo()
{
}
private static Lazy<Foo> fooLazy = new Lazy<Foo>(() => new Foo());
public static Foo Instance => fooLazy.Value;
}
There are some minor differences to what you were doing with static classes. If Foo was a static class, you would call Foo.Initialize(); As it is Singleton, you would call Foo.Instance.Initialize();
Any other methods or properties would most likely be non-static.
Pulling it all together, you could write code like this. Your queue does not need to know about the classes it holds. You don't actually care. You only want to know that it has the Initialize() method
public class YourClass
{
private Queue<IInitializable> objectsToLoad = new Queue<IInitializable>();
public void Enqueue(IInitializable obj)
{
this.objectsToLoad.Enqueue(obj);
}
public void LoadOrUpdate()
{
// Update Method
if (objectsToLoad.Count > 0)
{
IInitializable obj = objectsToLoad.Dequeue();
obj.Initialize();
}
else
{
// Loading complete.
}
}
}
This class could then be used like this
YourClass yourClass = new YourClass();
yourClass.Enqueue(Foo.Instance);
yourClass.LoadOrUpdate();
Though I hope there is a much better and more detailed answer than this; I've come up with a basic solution. I created a separate Queue<Type> where I add the static classes. I then call their Initialize method with the following:
Type t = typesToInit.Dequeue();
t.GetMethod("Initialize").Invoke(null, new object[] { 0 });
This works well and is rather clean, but I can't help but wonder if there is a better way to do this?
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
}
}
I came across the following code.
public class Test
{
public static Test Create()
{
return new Test
{
a1 =1,
b1="abc"
};
}
:
:
:
}
And in the calling class it is instantiated as below
static Test model = Test.Create();
What is the use of static keyword in the above line? What will be the difference if we don't use the static keyword? I'm using .NET 4 and VS 2010
EDIT
I know what is static in c#. The main reason I asked this question is why is it used when creating instance of class?
In this concrete presented code, don't see much sence of using this technique, but usually
you can do this in order to control your type instances creation.
For example: immagine that your class interacts with some COM object of the client, that can not be instantiated more the 10 times. To control that consumer of your API will not create more then 10 instances of your type, you can use this technique.
public class MyComWrapper {
private MyComWrapper () {} // MAKE CTOR PRIVATE SO NOONE CAN CREATE
// AN INSTANCE OF YOUR CLASS IF NOT WITH
// `static` METHOD CALL
static int counter = 0; //INSTANCE COUNTER
public static MyComWrapper Create()
{
if(counter >10) //MORE THEN 10, BAD !
throw new InvalidOperationException("Can not instantiate more then 10 instances");
counter ++;
return new Test
{
a1 =1,
b1="abc"
};
}
}
The static keyword makes it available without instantiating the object. The author is creating a function to instantiate the object in a specific way, but since it's the default constructor anyone can instantiate it.
Although not exclusively, along with making the constructor private, this is a pattern commonly used in the Singleton Pattern.
Static modifier belongs to the type itself rather than to a specific object.
You don't have to create an instance to use that static function. you can directly use the static function without creating an instance of the class.
If the static keyword is applied to a class, all the members of the class must be static.
It is simple. They are separate uses of static. The first one creates a static method in a non-static class. The second one create a static member of the "calling" class.
Your Test class itself is not static, so you are allowed to instantiate it.
To answer your question: if you do not use the static keyword in the calling class, it will be a "normal" instance member.
Ok, I have a singleton class GraphMaster which contains a number of system-wide values. I have a subclass GraphObject : GraphMaster which has graph specific data. By subclassing, I can access members of either the global class or subclass. And by using a singleton class, I can change the global variables anywhere and have them be reflected in all the subclasses.
However, I'm getting stuck because the base class's constructor wants to call the singleton class's constructor, but it can't as it's marked private.
how do I get around this? Is what I'm trying to do possible? I went down this path due to responses to this post: Can I make a "global" object to store variables for multiple objects?
For example,
public class GraphMasterObject {
private static GraphMasterObject instance;
private GraphMasterObject() { }
}
public static GraphMasterObject Instance {
get {
if (instance == null) instance = new GraphMasterObject();
return instance;
}
}
public int globalVar=10;
}
public class GraphObject : GraphMasterObject {
public GraphObject() {
}
public int localVar=20;
}
I want to be able to do
GraphObject go = new GraphObject();
go.globalVar <- this is 10
GraphMasterObject.Instance.globalVar = 20;
go.globalVar <- now this is 20
Ok, I have a singleton class GraphMaster which contains a number of system-wide values. I have a subclass GraphObject : GraphMaster which has graph specific data.
That's a problem to start with. As soon as you have a class which has subclasses, that it by definition not a singleton. Someone can add another subclass at any point, and even if you only have one instance of each subclass, you'll have two distinct instances which are compatible with the base class.
You could add something in the base class constructor to throw an exception if there's already an instance, but it would be pretty smelly. Fundamentally, singletons are incompatible with subclassing. Rethink your design. (Ideally, avoid the singleton pattern in the first place, but that's another matter...)
Although a static class has only one instance and can't be instantiated, a class with a private constructor can't be instantiated (as the constructor can't be seen), so every time you call this class, this is the same one instance?
Factory classes always follow the last convention (instance class with private constructor). Why is this?
Thanks
There's nothing stopping the class with the private constructor from having a public static method which returns instances of the class:
public class NoPublicConstructor
{
private NoPublicConstructor()
{
}
public static NoPublicConstructor NewInstance()
{
return new NoPublicConstructor();
}
}
As you can see, the static method does not return the same one instance.
edit: One of the reasons factory classes do this is to be able to separate responsibility in future versions: while your code always calls the factory creation method, the author may move all the "guts" out of that class into a different one and your code won't need to know the difference. Calling that class' (public) constructor ties it to an extent to the original class implementation.
You can't* get an instance from outside the class, but you can from inside. A static method or an inner class can create and return an instance of the class with a private constructor. The static class cannot be instanced by anything.
class Foo
{
private Foo()
{
}
public class Bar
{
public Bar()
{
}
public Foo GetFoo()
{
return new Foo();
}
}
}
..
Foo.Bar fooBar = new Foo.Bar();
Foo foo = fooBar.GetFoo();
Edit: *I use the term "can't" loosely. Brian Rasmussen pointed out in the comments to the OP that another method to obtain an instance is through a call through System.Runtime.Serialization.FormatterServices, and this is external to the class itself.
Foo foo = (Foo)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Foo));
Creating a class with private constructor is the common pattern for implementing a "Singleton" object.
The Singleton usually will instantiate an instance of itself, and only allow access to it through a static "Instance" property, which means there's only ever one instance of the class.
The advantage of using a Singleton over a purely static class is that you can utilize interfaces and different implementation classes within the singleton. Your "Singleton" might expose an interface for a set of methods, and you can choose which exact implementation class to instantiate under the covers. If you were using a purely static class, it would be hard to swap out a completely different implementation, without impacting other code.
The main downside of Singleton is that it's difficult to swap out the implementation class for testing, because it's controlled within the Singleton private methods, but there are ways to get around that.