Im folgenden Codebeispiel haben wir eine Klasse für unveränderliche Objekte, die einen Raum darstellt. Nord, Süd, Ost und West repräsentieren Ausgänge in andere Räume.
public sealed class Room
{
public Room(string name, Room northExit, Room southExit, Room eastExit, Room westExit)
{
this.Name = name;
this.North = northExit;
this.South = southExit;
this.East = eastExit;
this.West = westExit;
}
public string Name { get; }
public Room North { get; }
public Room South { get; }
public Room East { get; }
public Room West { get; }
}
Wir sehen also, dass diese Klasse mit einem reflexiven Zirkelbezug entworfen wurde. Aber weil die Klasse unveränderlich ist, habe ich ein Problem mit Hühnern oder Eiern. Ich bin mir sicher, dass erfahrene Funktionsprogrammierer damit umgehen können. Wie kann es in C # gehandhabt werden?
Ich bin bestrebt, ein textbasiertes Abenteuerspiel zu programmieren, aber ich verwende funktionale Programmierprinzipien nur zum Zweck des Lernens. Ich bleibe bei diesem Konzept und kann Hilfe gebrauchen !!! Vielen Dank.
AKTUALISIEREN:
Hier ist eine funktionierende Implementierung, die auf der Antwort von Mike Nakis bezüglich der verzögerten Initialisierung basiert:
using System;
public sealed class Room
{
private readonly Func<Room> north;
private readonly Func<Room> south;
private readonly Func<Room> east;
private readonly Func<Room> west;
public Room(
string name,
Func<Room> northExit = null,
Func<Room> southExit = null,
Func<Room> eastExit = null,
Func<Room> westExit = null)
{
this.Name = name;
var dummyDelegate = new Func<Room>(() => { return null; });
this.north = northExit ?? dummyDelegate;
this.south = southExit ?? dummyDelegate;
this.east = eastExit ?? dummyDelegate;
this.west = westExit ?? dummyDelegate;
}
public string Name { get; }
public override string ToString()
{
return this.Name;
}
public Room North
{
get { return this.north(); }
}
public Room South
{
get { return this.south(); }
}
public Room East
{
get { return this.east(); }
}
public Room West
{
get { return this.west(); }
}
public static void Main(string[] args)
{
Room kitchen = null;
Room library = null;
kitchen = new Room(
name: "Kitchen",
northExit: () => library
);
library = new Room(
name: "Library",
southExit: () => kitchen
);
Console.WriteLine(
$"The {kitchen} has a northen exit that " +
$"leads to the {kitchen.North}.");
Console.WriteLine(
$"The {library} has a southern exit that " +
$"leads to the {library.South}.");
Console.ReadKey();
}
}
Room
Beispiel.
type List a = Nil | Cons of a * List a
. Und ein binärer Baum: type Tree a = Leaf a | Cons of Tree a * Tree a
. Wie Sie sehen, sind beide selbstreferenziell (rekursiv). Hier ist , wie Sie Ihr Zimmer definieren würde: type Room = Nil | Open of {name: string, south: Room, east: Room, north: Room, west: Room}
.
Room
Klasse und von a List
in dem oben von mir geschriebenen Haskell ist.