user6369603
user6369603

Reputation:

How do I use a class of any type inside another class

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

Answers (3)

JaggerJo
JaggerJo

Reputation: 934

Interfaces

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();
    }
}

Dynamics

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

danish
danish

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

P.Brian.Mackey
P.Brian.Mackey

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

Related Questions