Frage

Ich habe eine Fabrikklasse namens Alarmfactory als solche erstellt ...

1    class AlarmFactory
2    {
3        public static Alarm GetAlarm(AlarmTypes alarmType)  //factory ensures that correct alarm is returned and right func pointer for trigger creator.
4        {
5            switch (alarmType)
6            {
7                case AlarmTypes.Heartbeat:
8                    HeartbeatAlarm alarm = HeartbeatAlarm.GetAlarm();
9                    alarm.CreateTriggerFunction = QuartzAlarmScheduler.CreateMinutelyTrigger;
10                    return alarm;
11
12                   break;
13                default:
14                
15                    break;
16            }
17        }
18    }

Herzschlag Alarm wird aus Alarm abgeleitet. Ich erhalte einen Kompilierfehler "kann den Typ nicht implizit konvertieren ... eine explizite Konvertierung besteht (fehlt Ihnen eine Besetzung?)". Wie kann ich das so einrichten, dass ein abgeleiteter Typ zurückgegeben wird?

BEARBEITEN

Vielen Dank für Ihre Antworten. Ich habe den Kompilierfehler innerhalb von zehn Minuten behoben, weshalb ich nicht den gesamten Fehler veröffentlicht habe. Aber ich schätzte die unterschiedlichen Ansätze, die erwähnt wurden.

Für die Aufzeichnung wurde "nicht implizit Typ" Goalarmscs.heartbeatalarm "in" Goalarmscs.Alarm "umwandeln. Eine explizite Konvertierung besteht (fehlt Ihnen eine Besetzung?)". (Ich glaube.) Der Fehler trat in Zeile 8 auf.

Seth

War es hilfreich?

Lösung

Im Folgenden finden Sie eine Lösung, die eine bestimmte Getheartbeatalarm -Funktion enthält, um ein Herzbeatalarm -Objekt sowie eine generische GetAlarm -Funktion abzurufen, um einen Alarm zurückzugeben, dessen Typ durch den generischen Parameter bestimmt wird. Unten gibt es einen Beispielcode, der zeigt, wie dies genannt wird:

enum AlarmTypes
{
    Heartbeat,
    AnotherAlarm,
    // ...
}

delegate void CreateTriggerDelegate();

class Alarm
{
    // ...

    public CreateTriggerDelegate CreateTriggerFunction { get; set; }
}

class HeartbeatAlarm : Alarm
{
    // ...

    public static HeartbeatAlarm GetAlarm()
    {
        return new HeartbeatAlarm();
    }
}

class QuartzAlarmScheduler
{
    public static CreateTriggerDelegate CreateMinutelyTrigger { get; set; }
}

class AlarmFactory
{
    public static Alarm GetAlarm(AlarmTypes alarmType)  //factory ensures that correct alarm is returned and right func pointer for trigger creator.
    {
        switch (alarmType)
        {
            case AlarmTypes.Heartbeat:
                return GetHeartbeatAlarm();
            default:
                throw new ArgumentException("Unrecognized AlarmType: " + alarmType.ToString(), "alarmType");
        }
    }

    static Alarm _GetAlarm<T>()
        where T : Alarm
    {
        Type type = typeof(T);
        if (type.Equals(typeof(HeartbeatAlarm)))
            return GetHeartbeatAlarm();
        else
            throw new ArgumentException("Unrecognized generic Alarm argument: " + type.FullName, "T");
    }

    public static T GetAlarm<T>()
        where T : Alarm
    {
        return (T)_GetAlarm<T>();
    }

    public static HeartbeatAlarm GetHeartbeatAlarm()
    {
        HeartbeatAlarm alarm = HeartbeatAlarm.GetAlarm();
        alarm.CreateTriggerFunction = QuartzAlarmScheduler.CreateMinutelyTrigger;
        return alarm;
    }
}

class Example
{
    static void GetAlarmExamples()
    {
        HeartbeatAlarm alarm;

        alarm = AlarmFactory.GetHeartbeatAlarm();

        alarm = AlarmFactory.GetAlarm<HeartbeatAlarm>();

        alarm = (HeartbeatAlarm)AlarmFactory.GetAlarm(AlarmTypes.Heartbeat);
    }
}

Andere Tipps

Ihre beste Wette wäre es zu machen Alarm Eine Schnittstelle oder wenn das nicht möglich ist, erstellen Sie eine IAlarm Schnittstelle und Erben von dieser Schnittstelle für beide Alarm und HeartbeatAlarm.

AlarmFactory.GetAlarm sollte wieder zurückkehren IAlarm Beispiel. Ebenfalls, HeartbeatAlarm.GetAlarm() sollte wieder zurückkehren IAlarm Beispiel.

Dies sollte alle Compiler-Fehler beseitigen, und der Vorteil ist, dass alle Beziehungen sauber vertraglich sind, was den Code so viel zukünftiger machen sollte.

Haben Sie versucht, was der Compiler vorschlägt?

return (Alarm) alarm;

Bearbeiten: Das ist völlig falsch, aber ich verlasse diese Antwort hier, um die Diskussion in den Kommentaren zu bewahren.

Wie einige bereits vorgeschlagen haben, ist eine redundante Schnittstelle eine einfache Möglichkeit, dies zu erreichen. Ein sauberes Beispiel scheint zukünftigen Besuchern zu helfen.

public interface IAlarm
{
    public int bpm { get; set; }    // declared base props
}

public class Alarm : IAlarm
{
    public int bpm { get; set; }    // implemented base props
}

public class HeartbeatAlarm : Alarm
{
    public int min { get; set; }    // extended type specific props
}

public class FactoryMethods
{
    public static T AlarmFactory<T>(int bpm) where T : IAlarm, new()
    {
        // interfaces have no constructor but you can do this
        T alarm = new T() {
            bpm = bpm
        };

        return alarm;
    }
}

// C# will automagically infer the type now..
HeartbeatAlarm heartbeatAlarm = FactoryMethods.AlarmFactory<HeartbeatAlarm>(40);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top