Reputation:
I have a class. Inside that class I wish to use a method from another class. However, I don't want to be restricted to only one type of class, I want to be able to call this method from any class that contains the method.
public class DialogueSuper : MonoBehaviour
{
public choiceHandler ch = null;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void end(){
ch.next()
}
}
In the end() method I call the ch.next() method. However, I do not want to be restricted to a class of choiceHandler. I would like to call the next() method on any class I decide to pass into DialogueSuper that contains a next() method.
Upvotes: 0
Views: 84
Reputation: 934
You generally do this by using Interfaces in C#.
A Interface is basically a contract. All classes that implement a Interface must provide the methods and properties specified in there.
interface IChoiceHandler
{
void next();
}
First Imlementation of the Interface
class ChoiceHandler1 : IChoiceHandler
{
public void next()
{
//do something
}
}
Another Imlementation of the Interface
class ChoiceHandler2 : IChoiceHandler
{
public void next()
{
//do something else
}
}
No you only require a class that implements the interface which defines the functionality you want.
class Example
{
public Example(IChoiceHandler handler)
{
handler.next();
}
}
It is also possible to use dynamics, but this is not recommended because it easily can create runtime errors.
class Example
{
public Example(dynamic handler) => handler.next();
}
Upvotes: 1
Reputation: 5600
What you are talking about is called Inversion of Control. You can implement that in the code through dependency injection. Basically the creator of DialogueSuper
class's object will have the power to choose the ChoiceHandler
. You can either make use of full blown IoC providers like Unity application block or write your own. For a simple need of this sort, you can probably write the DialogueSuper
class like this:
First, have an interface and implement that in the choice handler class.
public interface IChoiceHandler
{
void Next();
}
public class ChoiceHandler : IChoiceHandler
{
public void Next() { }
}
Next, update the dialogue class with one of these options:
public class DialogueSuper : MonoBehaviour
{
// Way 1: Property Injection
public IChoiceHandler ChoiceHandler
{
get; set;
}
// Way 2: Constructor injection
private IChoiceHandler _choiceHandler;
private DialogueSuper() : base()
{
}
public DialogueSuper(IChoiceHandler choiceHandler)
{
_choiceHandler = choiceHandler;
}
// Way 3: Method Injection
public void end(IChoiceHandler choiceHandler)
{
// For way 1
ChoiceHandler.Next();
// For way 2
_choiceHandler.Next();
// For way 3
choiceHandler.Next();
}
}
Note that first option is more suitable if you are using an IoC provider. With current code, you are prone to NullReferenceException
.
Upvotes: 1
Reputation: 44285
The standard approach to solving this problem is to program to an interface. choiceHandler
is presumably a concrete class thus the problem. Change this to IChoiceHandler
which contains the member Next
.
public interface IChoiceHandler
{
void Next();
}
Any class that implements the interface can be injected as a dependency.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueSuper : MonoBehaviour
{
public IChoiceHandler ch = null;
public DialogueSuper(IChoiceHandler ch)
{
this.ch = ch;
}
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void end()
{
ch.Next()
}
}
Upvotes: 2