[C#] Methode aanroepen in derived class

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 08-10 00:28
Ik ben bezig met een applicatie voor de Microsoft HoloLens met C# en Unity maar loop tegen een OO programming probleempje aan.

Ik heb een script dat verantwoordelijk is voor het selecteren en verplaatsen van hologrammen. Dit script komt uit de standaard HololensToolkit en heet TapToPlace.cs. Daarnaast heb ik een script dat de positie van hologrammen via het netwerk deelt, deze heb ik zelf geschreven en heet NetworkObject.cs.

Het NetworkObject script moet bij een aantal publieke variabelen uit TapToPlace.cs kunnen. Maar TapToPlace.cs die een listener heeft voor bepaalde handgebaren heeft moet ook een methode uit NetworkObject kunnen aanroepen.

Voor een nette werking van het programma is het belangrijk dat deze scripts gescheiden blijven. Want TapToPlace moet ook op lokale objecten (die niet via het netwerk gedeeld worden) werken . Het is waarschijnlijk geen nette oplossing om een bidirectional association te maken tussen TapToPlace en NetworkObject.

Zelf zit ik eraan te denken om NetworkObject te laten ervan van TapToPlace. Netwerk objecten hebben namelijk ook altijd een TapToPlace script nodig en kunnen op deze manier gemakkelijk bij de variabelen uit TapToPlace. Het enige dat nu nog moet gebeuren en waar ik niet helemaal uitkom. Hoe kan de base class TapToPlace een methode uit de derived class NetworkObject aanroepen wanneer TapToPlace een bepaald handgebaar ziet?

Hieronder een sterk vereenvoudigde weergave van beide scripts:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TapToPlace : MonoBehaviour, IInputClickHandler
{
    public bool IsBeingPlaced;

    public virtual void OnInputClicked(InputClickedEventData eventData)
    {
        IsBeingPlaced = !IsBeingPlaced;
        // Roep objectIsBeingPlaced() uit NetworkObject aan
    }
}

public class NetworkObject : TapToPlace
{
    public void objectIsBeingPlaced()
    {
        // Do Something
    }
}

Acties:
  • 0 Henk 'm!

  • expor
  • Registratie: Juni 2005
  • Laatst online: 01-10 22:53
Misschien heb ik je vraag verkeerd begrepen maar ik doe toch een poging. Ik ben niet zo thuis in C#, maar als TapToPlace een (pure) virtual method objectIsBeingPlaced() heeft dan kan je die aanroepen in je OnInputClicked?

Edit: heb me even verdiept in C#, als TapToPlace een abstract method objectIsBeingPlaced() heeft en je die implementeert in elke derived class van TapToPlace, kan je in OnInputClicked die functie aanroepen.

Voorbeeld (note: eerste keer dat ik C# schrijf, het gaat om concept, de uitvoering zal waarschijnlijk beter kunnen...):
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    public abstract class BaseObject
    {
        public void process() { objectIsBeingPlaced(); }
        public abstract void objectIsBeingPlaced();
    }
    
    public class NetworkObject : BaseObject
    {
        public override void objectIsBeingPlaced() { Console.WriteLine("NetworkObject::objectIsBeingPlaced()"); }
    }
        
    public class LocalObject : BaseObject
    {
        public override void objectIsBeingPlaced() { Console.WriteLine("LocalObject::objectIsBeingPlaced()"); }
    }
    
    public class Program
    {
        public static void Main(string[] args)
        {
            BaseObject networkObject = new NetworkObject();
            networkObject.process();
            
            BaseObject localObject = new LocalObject();
            localObject.process();
        }
    }


Edit2: TapToPlace is uit de kit zie ik nu dus je zal of onderstaande van scrappy moeten volgen of een eigen interface toevoegen.

[ Voor 85% gewijzigd door expor op 21-07-2017 11:26 ]

AMD 5800X3D | 16gb DDR 4 @ 3800/14 | 4070 Ti | 1TB Samsung Evo 970, 1TB Samsung Evo 860, 512MB Crucial


Acties:
  • 0 Henk 'm!

  • scrappy.doo
  • Registratie: September 2004
  • Laatst online: 07-10 03:46
Aangezien NetworkObject derived van TapToPlace zou je OnInputClicked kunnen overriden:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public class TapToPlace : MonoBehaviour, IInputClickHandler
    {
        public bool IsBeingPlaced;

        public virtual void OnInputClicked(InputClickedEventData eventData)
        {
            IsBeingPlaced = !IsBeingPlaced;
        }
    }

    public class NetworkObject : TapToPlace
    {
        public override void OnInputClicked(InputClickedEventData eventData)
        {
            base.OnInputClicked(eventData);
            objectIsBeingPlaced();
        }

        public void objectIsBeingPlaced()
        {
            // Do Something
        }
    }

[ Voor 4% gewijzigd door scrappy.doo op 21-07-2017 11:22 ]


Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 08-10 00:28
scrappy.doo schreef op vrijdag 21 juli 2017 @ 11:20:
Aangezien NetworkObject derived van TapToPlace zou je OnInputClicked kunnen overriden:
Ik ga dit testen, als het werkt zou het wel een hele eenvoudige en nette oplossing zijn voor het probleem. Ik had het zelf al geprobeerd via een delegate in TapToPlace en dat werkt op zich wel maar is niet zo elegant als deze oplossing.

Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Erven moet je eigenlijk alleen gebruiken voor 'is a' relaties zoals bijvoorbeeld Student is een Persoon.

Een mogelijke oplossing hier is denk ik een event in TapToPlace maken. Het NetworkObject weet dan wel van je TapToPlace object en voegt daarin eventHandlers toe. Andersom hoeft TapToPlace dan NetworkObject niet te kennen.

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 08-10 00:28
Daos schreef op vrijdag 21 juli 2017 @ 11:48:
Erven moet je eigenlijk alleen gebruiken voor 'is a' relaties zoals bijvoorbeeld Student is een Persoon.

Een mogelijke oplossing hier is denk ik een event in TapToPlace maken. Het NetworkObject weet dan wel van je TapToPlace object en voegt daarin eventHandlers toe. Andersom hoeft TapToPlace dan NetworkObject niet te kennen.
Dat is ook een mooie oplossing. TapToPlace is eigenlijk een wat ongelukkige naam. Je kunt TapToPlace misschien beter lezen als MoveableObject of PlaceableObject. NetworkObject is ook een MoveableObject.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Maarten Kroon schreef op vrijdag 21 juli 2017 @ 12:10:
[...]
Dat is ook een mooie oplossing. TapToPlace is eigenlijk een wat ongelukkige naam. Je kunt TapToPlace misschien beter lezen als MoveableObject of PlaceableObject. NetworkObject is ook een MoveableObject.
Dan nog is erven *vaak* niet de beste methode, soms wel.

De minste coupling krijg je als je beide objecten events laat gooien, die je door een derde object (misschien een factory achtig ding) aan elkaar laat knopen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1