Instanced extension methods? C# - c#

So I would like to create an extension method for a Type that the api has otherwise sealed.
If you know about extension methods the following should look familiar.
private static List<Member> memberList = new List<Member>();
public static List<Member> GetMemberList(this GameObject go)
{
return memberList;
}
Notice that to declare an extension method, it needs to be static, and because it needs to be static, the List that Im accessing through the GameObject type has to be static to.
I would like each GameObject to have its own list of Members. However Im pretty sure since this is a static field every instanced GameObject will point to the same static memberList.
So would my assumptions be true? And if so, what might be an alternative? I would like to avoid putting the GameObject in a wrapper class that also holds the memberList because the api only allows GameObjects to be detected and manipulated at runtime. There are ways to reverse reference the wrapper class through the gameObject but that adds a lot more complexity to the code i would like to avoid.

Yes, if you want to keep something outside the game object and access it through the extension method, it would have to be static.
You can use a dictionary to map one member list to each game object:
private static Dictionary<GameObject, List<Member>> memberLists = new Dictionary<GameObject, List<Member>>();
public static List<Member> GetMemberList(this GameObject go) {
return memberLists[go];
}

It appears you are working with Unity3. There is a related answer on the UnityAnswers site that may help: http://answers.unity3d.com/questions/22493/unity-3-sealed-class-gameobject-.html
It appears that there should be ways to attach the behaviors you want inherent in the Unity framework using the builtin scripting system.

Yes, you are right. If you have a static method, all instances of that class share the same data. The call return memberList; is illegal. It is the same as return this.memberList; and this is not available in a static method. Instead you'd have to call the class: return GameObject.memberList;. But I understand that you are not looking for this solution.
Extension methods are meant to create additional behavior. If you want to create additional data, extending the GameObject class using inheritance is the right choice.
Alternatively you could attach the memberList by using a dictionary of the form Dictionary<GameObject, List<Member>>. But personally I'd favor composition as shown below:
public class myGameObject
{
public List<Member> memberList { get; set; }
public GameObject go { get; set; }
}

private static ConditionalWeakTable<GameObject, List<Member>> dict = new ConditionalWeakTable<GameObject, List<Member>>();
public static List<Member> GetMemberList(this GameObject go)
{
return dict.GetOrCreateValue(go);
}
ConditionalWeakTable manages the object lifetime, because it uses weak-references. Therefore it doesn't stop the GC from collecting the GameObject if it there are no other live references to it, and this will also allow the List<Member> to be collected.
It is threadsafe, but this assumes that you want your starting point to be an empty list (the default constructor is called in GetOrCreateValue if there isn't a current value). If you want a different starting point, your threading issues become more complicated.

Extension methods are simply just static methods that "appear" to look like instance methods.
They however, do not add any additional functionality a static method doesn't, it's just for ease-of-use, maintenance, and readability. Extension methods cannot access protected / private members either.
If GameObject is not actually sealed (ie it doesn't have the sealed keyword), then you can write a class that inherits GameObject to gain access to its protected methods/fields/properties. This will only work if you yourself are the one constructing these objects.

Related

Member '<method>' cannot be accessed with an instance reference error in Singleton Unity

I've seen this question several times on the site, however most of the solutions seem to indicate that I should just make it an instance variable rather than a static one. However, the whole point of the Singleton pattern is this static object that's consistently referred to. Here are the links I have looked at:
Member cannot be accessed with an instance reference; qualify it with a type name
Member '<method>' cannot be accessed with an instance reference
This last link led me to the following:
What does the 'static' keyword do in a class?
And I feel I do understand this. The point of the Singleton is that all classes share this one instance so it feels perfect? I don't see the issue? It should be static according to Singleton conventions and frankly logic.
I'm in unity and am trying to make an inventory system for a game some fellow students and I are trying to make. I have the InventoryUI set up, however I would like to build a static inventory that is ever-present in the game. The InventoryUI will draw the necessary data from this Singleton class.
In other words, the PlayerInventory will act as the backend for the InventoryUI. The PlayerInventory will be a Singleton and the InventoryUI will draw the necessary data from PlayerInventory
Here is the relevant code for my Singleton class:
public class PlayerInventory : MonoBehaviour
{
private static PlayerInventory instance;
private PlayerInventory() { }
public static PlayerInventory getInstance()
{
if (instance == null)
return instance = new PlayerInventory();
return instance;
}
}
Here is the relevant code for my InventoryUI class:
public class PlayerInventoryUI : MonoBehaviour
{
//Inventory Instance
static PlayerInventory inventory;
void Start()
{
inventory = inventory.getInstance();
//cannot be accessed with an instance reference Error occurs here.
}
}
If possible, could someone explain to me why this error occurs as well as a possible solution.
That static method is in the class, not in an instance. So change your code in InventoryUI to this:
public class PlayerInventoryUI : MonoBehaviour
{
//Inventory Instance
static PlayerInventory inventory;
void Start()
{
inventory = PlayerInventory.getInstance();
//works because static methods are called from the class
}
}
I use Singletons with Unity a lot, have shared my pattern in a Quora answer: https://qr.ae/TSqaWt
Oh and if your Inventory is not in some GameObject Script component, it does not need to inherit from MonoBehaviour. Is better to use just a plain C# class if you don't need to use MonoBehaviour things like having Unity call Update on it.
If you wan't to have it as a script component, which can be nice to have it show in the inspector etc, then you should not 'new' it yourself but let Unity create it and assign the instance to the static reference when that happens. Is good to do that in Awake() so the singleton is already there when other scripts do Start()
Try the following instead:
inventory = PlayerInventory.getInstance();
You are attempting to call a static method on an (uninitialized) instance variable which is not allowed. Static methods must be qualified with the type (class) name, as the error suggests.
You have defined a static method inside a non static class, and although it's perfectly legal, the two should be thought of as seperate entities. Static methods only have access to static fields of the class, they cannot access any instance variables. The memory of static data members is allocated individually without any relation with the object.
Look at String.Parse() as an example, you wouldn't write mystring.Parse(), but instead you use the static method Parse of the String class which is always available and does not require a new string instance to use.
Hope this helps, if any further questions I will try to explain better.

C# Put Static Class Inside Dictionary

I was unclear in an earlier question I ask so I will try to be more explicit.
Is there a way to put a static class inside of a dictionary so that its functions can be called? If this is not possible, what is the best alternative that doesn't involve using instances that you can suggest?
Here is how I would like to use it:
static class MyStatic : IInterface
{
static void Do(){}
}
static class MyStatic2 : IInterface
{
static void Do(){}
}
class StaticMap
{
static Dictionary<Type,IInterface.class> dictionary = new Dictionary<Type,IInterface.class>
{
{Type.1, MyStatic}
{Type.2, MyStatic2}
};
}
// Client Code
class ClientCode
{
void Start()
{
StaticMap.dictionary[Type.1].Do();
}
}
There are some fundamental reasons why you can't do that directly:
Static method calls are bound at compile-time
Static calls are not inherited - they are tied to the class that defines them
There is no implicit base type (and therefore no polymorphism) between static methods, even if the name, inputs, and outputs are all the same
Since your signature is the same for every static method, you could store a Action in the dictionary instead:
static Dictionary<Type,Action> dictionary = new Dictionary<Type,Action>
{
{Type.1, MyStatic.Do}
{Type.2, MyStatic2.Do}
};
then you can call the Action directly:
void Start()
{
StaticMap.dictionary[Type.1]();
}
It's slightly repetetive because you have to specify the method name in the dictionary as well, but it's type safe.
A key question is whether you want to call a single method on each type or whether you need to call multiple methods belonging to each type.
If it's just a single method, then what D Stanley suggested is the answer. If you store a number of Actions, each representing a method with the same signature on a different static class, then you're accomplishing what you said.
However that raises a question - why the constraint that each method must belong to a separate static class? This approach would work just as well if some or all of the methods belonged to the same class.
If you need to call more than one method from each class then an Action no longer works. You'd have to store collections of Action, which a) means class instances, and b) is a lot more complicated than just using interfaces and class instances.
One way to manage instances is by using a dependency injection container to create class instances for you. Using that approach, you can create non-static classes without having to go through the hassle of explicitly making them singletons. But you can tell the container to only produce one of each and reuse it. For example, using Castle Windsor:
container.Register(Component.For<ISomeInterface,SomeClass>));
Now every time the container is asked to provide an instance of ISomeInterface it will always provide the same instance of SomeClass.
Because the dependency you're looking for varies by type (Dictionary<Type, Something>) it sounds like what you're looking for might be related to generics. But it would be necessary to take a step back from the smaller problem and understand a slightly larger picture of what you're trying to accomplish.
Instead of having the entire class as static, create a Singleton instance.
public class Foo
{
public static Foo _Foo;
public Foo()
{
_Foo = this;
}
}
Then you may add it to your list, and also inherit from Interfaces, etc.

Finding and starting a generic class?

I have a Unity C# application where every game inside has one abstract controller. It inherits from another class enabling it to be accessed like a static version of the base behavior in unity.
public class AbstractController<T> : SingletonMonoBehavior<T> {
virtual public void Begin() {
//startup code here
}
}
So, to find this class, I have to know what T will be. Do I need reflection for this? Or can I just store T types in a List somewhere, and access them dynamically? Right now, I DO have a dictionary of game names and classes that inherit from abstract controllers -- so I know what T is supposed to be, but when I do this:
_controllerTypes = new Dictionary<GameScene, Type> ();
_controllerTypes.Add (GameScene.FrogJump, typeof(FJGameController));
Type T = _controllerTypes [_startScene];
AbstractController<T>[] controllers = GameObject.FindObjectsOfType<AbstractController<T>> ();
I get a compiler error stating that "The type or namespace name `T' could not be found." Is there a way to design around this? I don't want to use reflection, but I want it to be pretty.
What you are about to do is absolutely possible but requires the use of reflection. You shouldn't do this as it will affect the performance of your game. Like Catlard mentioned in the comment section, use interface.
interfaces allow you to guarantee that a class has a function, but how
do you access that class in the first place? You can't just
GetComponent for all IControllable interfaces, for example. I'd still
have to have an abstract controller class, right?
You can use GetComponent to check for an interface.
public class Player : MonoBehaviour, IControllable
{
}
then your Interface:
public interface IControllable
{
}
Now, lets say that your Player script is attached to a GameObject called "Player".
GameObject plyrObj = GameObject.Find("Player");
if (plyrObj.GetComponent<IControllable>() != null)
{
Debug.Log("Player is Controllable");
}
Your can also have multiple interface for different classes. You can also make the interface generic with something like public interface IControllable<T>{}. This should help you re-do your work.

C# in Unity 3D/2D: Am I required to use Classes for every script?

A little background: I'm new to C# and Unity, but catching on very quickly. I'm also hoping this thread will not spark a debate about the merits of classes and abstract coding, as that debate is unrelated and well-worn (and unnecessarily heated); so please keep that in mind.
I'm simply wondering if every C# script in Unity is required to have a main class in any way or for any reason.
Or instead, can methods, and variables can be written outside of a class in a blank file (with namespaces) to be used in a video game?
I'm asking because, when I create a new C# script, it seems to force a class into my file and I'm afraid of breaking things.
I hope to keep code abstraction to a minimum, and the current project
I'm working on has several situations where a class is not needed, or
only one instance of the class will be used. I'd like to simply avoid
using classes in those cases.
In terms of declaring/defining variables and methods outside of any class, you can't really do that in C#. It just isn't how the language was designed (the answers to the question I linked to expand on that idea, so I won't duplicate them here).
You're not without options, though; if you have a number of variables or methods that need to be accessible from different places and don't need an object reference, you can make them static, so you won't need to instantiate the class to make use of them:
public class UtilityClass
{
public static float GravityConstant = 3.51f;
public static string GameName = "MyFirstGame";
public static float CalculateProduct(float a, float b)
{
return a * b;
}
}
Then, you can reference the class's methods/members by accessing it through its name:
float product = UtilityClass.CalculateProduct(6, 1.5f);
An example of where you might use this pattern is when defining mathematical formulae which aren't included in Unity's Mathf methods, and using them in multiple classes.
Additional note: Creating a new C# script through Unity's editor UI will default to declaring a class of the same name that inherits from Monobehaviour. You can alter it to remove the inheritance from Monobehaviour if you don't need any of the methods/attributes of the class, which avoids unnecessary overhead. One example for this would be with a static class that you never need to instantiate.
Yes, you are.
In C#, things like global variables and functions just do not exist. Everything must be contained in a class.
"But what should I do in order to declare some stuff that can be accessed everywhere, without creating an object?" you asked. There is something called the static modifier. You can access the methods or variables or fields or properties marked with this modifier without creating an object of that class.
You just add the word static in a method and it becomes a static method! How simple!
Let's see an example.
I have this non-static method:
public class MyClass {
public void DoStuff () {
}
}
I can call it like this:
var obj = new MyClass();
obj.DoStuff();
But if I modify it with static,
public class MyClass {
public static void DoStuff () {
}
}
I can call it like this:
MyClass.DoStuff();
How convenient!
Note:
Please do not misuse the static modifier! Only use it when it makes sense! When? When the method is a utility method or when the method does not belong to individual objects but the class itself.
First of All you need to check where Methods define as offical
docs stated
"Methods are declared in a class or struct by specifying the access
level such as public or private...."
So, Method should be declare in a Class or struct and A given class
should be, ideally, responsible for just one task.(see also)
Your this question "Or instead, can methods, and variables can be
written outside of a class in a blank file (with namespaces) to be
used in a video game?" answer is hidden in the below question.
Can there be stand alone functions in C# without a Class?
No. Make them static and put them in a static utility class if they indeed don't fit within any of your existing classes.
You have to make a class in order to use methods or its variable
either instance class or static class.
Am I required to use Classes for every script? Every script means you required a class. Unity Support Component Based
Architectural Design and if you require any script related
work then you definitely require a script component which means a
class require.
Finally for singleton, thanks to Unity3dWiki great detail
available. I think you will be feel comfortable to code and writing
class if you keep in mind component based architecture of Unity3d.
Singleton vs Static: I will also recommend to check this: Why do you use a Singleton class
if a Static class serves the purpose
Hope it will help.
[Note: If this helpful Any one can update this answer for future reference and use].

how to create a static list of objects within their constructor in c#?

I want to maintain a list of all instances of my class that are created. I thought I could do that by adding 'this' to a static list from within the constructor. Of course C# doesn't let me reference 'this' in the constructor because it's not fully constructed yet. That makes sense but I'm trying to figure out the best way to accomplish this.
class Thing
{ static List<Thing> AllTheThings;
public Thing()
{
AllTheThings.Add(this); // can't reference 'this' here
}
}
I can think of two ways to this:
Make the constructors private and create a static method ('MakeNewThing') that invokes the constructor and adds the new instance to the list. I worry about potential problems with not having a public constructor but I'm not sure what they are.
Create a shell class ('ThingShell') that contains Thing's. The constructor for ThingShell creates a Thing and adds it to the list. This is messy and requires ThingShell to proxy all of Thing's members.
I seem to remember doing something like this in C++ about 20 years ago but don't recall the details and can't find the code.
Anyone have a better ideas?
As #Jon Skeet said, that reference to "this" should have been fine. But just in case, here is an alternate method.
public class Thing
{
public readonly static List<Thing> AllTheThings = new List<Thing>();
//making the constructor private so that no other code can call it.
private Thing() { }
//providing a static instance method for creating the object
public static Thing Instance()
{
var t = new Thing();
Thing.AllTheThings.Add(t);
return t;
}
}
Now, the thing (excuse the pun) to watch out for in this implementation is that, by having this static list of all "Things" instantiated by the app, you will run the risk of a memory sinkhole if you do not have a way to get rid of old "Things" when they are no longer needed within scope.

Categories