Instantiate a Singleton in c# - c#

I'm trying to instantiate an object with a singleton in c#.
private static Mario __instance;
public static Mario Instance
{
get
{
if (__instance == null)
{
__instance = new Mario(); //TODO correct this vector
}
return __instance;
}
}
public Mario()
{
position = Vector2.Zero;
theatre = XNATheatre.Theatre;
ActionState = new IdleState();
PreviousState = ActionState;
ActionState.Enter(null);
isFacingRight = true;
}
I also have an idlestate class that is being instantiated in mario's constructor:
public IdleState()
{
mario = Mario.Instance;
Console.WriteLine(mario);
}
What seems to be happening is the _instance variable in my singleton always remains null, therefore it keeps returning new instances of mario, exactly the opposite of what I want it to do. I'm not exactly sure how to get around this.

You have a circular dependency...
When instantiating a Mario you instantiate an IdleState which calls Mario.Instance instantiating a new Mario and repeat.

Related

What wrong with that singleton implementation

I wrote static singleton and add class inside the Singleton class.
However, it seem like it broke the pattern.
any advice why?
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public int MyProperty { get; set; } = 10;
static Singleton() { }
private Singleton() { }
public static Singleton Instance {get { return instance; } }
public class SecondSingleton
{
public Singleton secondInstance;
public SecondSingleton()
{
secondInstance = new Singleton();
secondInstance.MyProperty = 20;
}
}
}
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.Instance;
Singleton.SecondSingleton s2 = new Singleton.SecondSingleton();
Console.WriteLine($"s1.MyProperty = {s1.MyProperty}");
Console.WriteLine($"s2.MyProperty = {s2.secondInstance.MyProperty}");
Console.ReadLine();
}
}
Asper WIKI : Singleton restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.
The moment you say "SecondInstance", then it is broke the pattern.
You are creating new Singleton in SecondSingleton constructor, which means secondInstance != Singleton.Instance. Instead, you should get the Instance, i.e: secondInstance = Singleton.Instance;

.net access local variable inside of class

I am new to C# and the .Net framework and struggling to understand how to do something. Do I lean on Inheritance for something like this?
When the variable allDim is true, I want all class instances to return 0 for their dimPercent.
public class Program
{
//if this is true, all rooms should return 0
public bool allDim = false;
public class Room
{
//0 is lights out. 100 is as bright as possible
public Room(int dimPercent)
{
DimPercent = dimPercent;
}
private int dimPercent;
public int DimPercent
{
get
{
if (Program.allDim)
{
//if allDim is true, all lights should be dimmed to 0 percent
return 0;
}
else
{
return dimPercent;
}
}
set
{
dimPercent = value;
}
}
}
public static void Main()
{
Room livingRoom = new Room(80);
Room kitchen = new Room(85);
Room bedroom = new Room(65);
allDim = true;
// This should return 0 since allDim was set to true
Console.WriteLine(kitchen.DimPercent);
}
}
Creating a base class that holds allDim and allowing the Room class to be derived from this new base class did not feel right to me since allDim is technically not a property of each class instance. Apologies if I butchered some of the terminology.
If you make allDim into a private static field then you would easily achieve what you want. However from the point of responsibility, you should ask yourself if any of the room instances should be able to affect other rooms?
public class Room
{
private static bool allDim = false;
// I am not sure if we should make this into a static method
public void SetAllDim(bool isAllDim){
allDim = isAllDim;
}
...
}
Convert your boolean into a Static Member of the class.
public static bool allDim = false;

Dictionary of different types, where the pulled object must remember its type, best approach?

I'm trying to find the best way to create a dictionary that can hold 6 different sub-types of the abstract Reward type, while also remember the individual item's original sub-type when pulled out again. Several approaches have worked, but I feel like they were all sub-par and that there must be better solutions.
Solutions that works, but I think could be improved on:
A list for each reward sub-type. (Will not scale well as I add large amounts of sub-types)
A list of lists. (This is both ugly and seems inefficient)
Multidimensional array. (Same issues as a list of lists)
Here are the relevant class snippets for my scenario:
public class RewardAssetContainer : MonoBehaviour
{
// Sounds
private static AudioClip losenedBowels = new AudioClip();
public static AudioClip LosenedBowels { get { return losenedBowels; } }
}
public abstract class Reward
{
protected EffectTypes effectType;
protected Rareity rareity;
protected Sprite itemIcon;
protected string itemName;
protected GameObject specialEffect;
}
interface iSoundEffect
{
void SetVolume(float _newVol);
void PlaySound();
void StopSound();
}
class DeathSoundEffect: Reward, iSoundEffect
{
private AudioSource sound;
public DeathSoundEffect(string _itemName, AudioClip _sound, float _vol, EffectTypes _effectType, Rareity _rareity, Sprite _itemIcon)
{
sound = new AudioSource();
itemName = _itemName;
sound.volume = _vol;
sound.clip = _sound;
effectType = _effectType;
rareity = _rareity;
itemIcon = _itemIcon;
}
public void PlaySound()
{
sound.Play();
}
}
public class Item_Inventory : MonoBehaviour
{
private static Dictionary<string, Reward> rewardItemsOwned = new Dictionary<string, Reward>();
public static Reward GetSpecificItem(string _keyValue) { return rewardItemsOwned[_keyValue]; }
private void TestPutToInventory()
{
rewardItemsOwned.Add("LosenedBowels", new DeathSoundEffect("LosenedBowels", RewardAssetContainer.LosenedBowels, 0.5f, EffectTypes.DeathSoundEffect, Rareity.Rare, RewardAssetContainer.EpicExample));
}
}
I would like to, in a different class, be able to do something like:
var tempRewardItem = Item_Inventory.GetSpecificItem("LosenedBowels");
tempRewardItem .PlaySound();
But i can't figure out an elegant way to do this with one collection.
Will you always know the original sub-type you expected ahead of time when pulling out an item, like in your example? If so, you can attempt to cast the object you pulled out before using it:
var tempRewardItem = Item_Inventory.GetSpecificItem("LosenedBowels") as DeathSoundEffect; // Could also use 'as isSoundEffect'
if (tempRewardItem != null)
{
tempRewardItem.PlaySound();
}

Unity3D Singleton with using Constructor of MonoBehavior

I have several MonoBehavior subclasses that need to be a Singleton however assigning an Instance property in Awake() is too late for some classes and results in race conditions so I was wondering is there anything that speaks against assigning Instance in a private c-tor, like this:
public class Foo: MonoBehaviour
{
public static Foo Instance { get; private set; }
private Foo()
{
Instance = this;
}
}
Or are there any negative side effects to this approach that I need to be aware of?
I agree with Lorek's answer but there is one problem with it.
You shouldn't use the constructor of a MonoBehavior as that itself has undesired behaviors. Since it will not be part of a specific GameObject. So you will have to add it to the Init, Awake or Start method of that Behavior; Or create a new class to contain the logic you want to share. (The new class should not be extended by the MonoBehavior class)
And then create a singleton as Lorek describes above.
You could also change the Script Execution Order to make sure that your MonoBehavior that needs to work as a "singleton" being executed before all other scripts.
However, it will be necessary to already have this MonoBehavior attached to an existing GameObject in the scene and not added automatically/by code.
http://docs.unity3d.com/Manual/class-ScriptExecution.html
The technique you are using allows the Instance property to be set more than once, even though if only by other members of the same class. That is a no-no. I would do something like this:
private static readonly Foo instance = new Foo();
public static Foo Instance
{
get
{
return instance;
}
}
This is a simple way to be certain the singleton variable is set only once. If you want lazy instantiation you could do something like this:
private static Foo instance = null;
public static Foo Instance
{
get
{
if (null == instance)
instance = new Foo();
return instance;
}
}
But with this technique you could still write to your instance variable more than once. So, you'll need to make sure you always reference the property and not the variable. And if this property is going to be accessed from multiple threads you'll want to prevent race conditions by using a critical section like this:
private static readonly object singletonSection = new object();
private static Foo instance = null;
public static Foo Instance
{
get
{
if (null == instance)
{
lock(singletonSection)
{
if (null == instance)
instance = new Foo();
}
}
return instance;
}
}
This is the double-checked locking pattern. You could use regular locking if the code is not accessed much and/or performance is not a problem.
Thanks for the input anyone! I eventually came up with the following method because in my case those Singletons are created via the Editor (from a menu) and the singletons should be components on a container game object.
public static T GetInstance<T>(string containerName) where T : Component
{
/* Find container or create if it doesn't exist. */
var container = GameObject.Find(containerName);
if (container == null) container = new GameObject(containerName);
/* Get existing instance or create new one if not found. */
return container.GetComponent<T>() ?? container.AddComponent<T>();
}
Of course it's not perfect either because it relies only on object names. But it works for me.
MonoSingleton class is useful if you need to have a single global MonoBehaviour script accessible from anywhere. Here is the MonoSingleton class:
using UnityEngine;
public class MonoSingleton<T> where T : MonoBehaviour
{
private static T _instance;
private static bool isFound;
private bool createMissingInstance;
static MonoSingleton()
{
isFound = false;
_instance = null;
}
public MonoSingleton(bool createNewInstanceIfNeeded = true)
{
this.createMissingInstance = createNewInstanceIfNeeded;
}
public T Instance
{
get
{
if (isFound && _instance)
{
return _instance;
}
else
{
UnityEngine.Object[] objects = GameObject.FindObjectsOfType(typeof(T));
if (objects.Length > 0)
{
if (objects.Length > 1)
Debug.LogWarning(objects.Length + " " + typeof(T).Name + "s were found! Make sure to have only one at a time!");
isFound = true;
_instance = (T) System.Convert.ChangeType(objects[0], typeof(T));
return _instance;
}
else
{
Debug.LogError(typeof(T).Name + " script cannot be found in the scene!!!");
if (createMissingInstance)
{
GameObject newInstance = new GameObject(typeof(T).Name);
isFound = true;
_instance = newInstance.AddComponent<T>();
Debug.Log(typeof(T).Name + " was added to the root of the scene");
return _instance;
}
else
{
isFound = false;
return null; // or default(T)
}
}
}
}
}
}
Then define MonoSingletons inside a static class. For example:
public static class Global
{
public static MonoSingleton<GameProgress> progress = new MonoSingleton<GameProgress>(true); //true means that new GameObject with script GameProgress will be created if it is missing from the scene
public static MonoSingleton<CharacterController> characterController = new MonoSingleton<CharacterController>(false); //will return null if there is no character controller present in the scene.
}
And then simply access global MonoBehaviors from any script!
Global.progress.Instance.score++;

How to easily simulate the not-thread-safeness of this Singleton pattern?

According to Jon Skeet's article, the following pattern is bad as it is not thread safe.
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance = null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
I have not learnt threading yet so it is a bit abstract to me. Could you give me a simple code to simulate the threading problem (we get notified when the problem occurs)?
Well thats pretty simple, just let something access a property within your singleton in parallel, for example like this console app.
class Program
{
static void Main(string[] args)
{
var threads = Enumerable.Repeat(new Action(() => Console.WriteLine(Singleton.Instance.guid)), 10);
Parallel.ForEach(threads, t => t());
Console.Read();
}
}
(I've added a guid property to your class to test that)
public sealed class Singleton
{
public Guid guid = Guid.NewGuid();
private static Singleton instance = null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
The issue with this singleton implementation is that 2 threads can access the getter simultaneously and each one will create a new instance. So the first thread might end up with a different instance than the second one... which can lead to unexpected behavior.
This is just in reply to OP comment:
static void Main(string[] args)
{
int test = 5;
Task<Singleton>[] arr =
{
Task<Singleton>.Factory.StartNew(() => Singleton.Instance),
Task<Singleton>.Factory.StartNew(() => Singleton.Instance),
};
Task.WaitAll(arr);
foreach (var item in arr)
{
Singleton s = item.Result;
s.MyProperty = test++;
Console.WriteLine(s.MyProperty);
}
}
MyProperty is just an int property i added.

Categories

Resources