Bitten Sie eine generische Methode, bei FAIL einen bestimmten Ausnahmetyp auszulösen

StackOverflow https://stackoverflow.com/questions/41397

  •  09-06-2019
  •  | 
  •  

Frage

Stimmt, ich weiß, dass ich damit völlig wie ein Idiot aussehen werde, aber mein Gehirn ist einfach nur verrückt nicht Ich lege heute Morgen meinen Gang ein.

Ich möchte eine Methode haben, mit der ich sagen kann: „Wenn es schief geht, kommen Sie mit dieser Art von Ausnahme zurück“, oder?

Zum Beispiel so etwas wie (und das funktioniert nicht):

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = new Exception(message);
        return ex;
    }

Was mich jetzt verwirrt, ist, dass wir WISSEN dass der generische Typ aufgrund von ein Ausnahmetyp sein wird Wo Klausel.Der Code schlägt jedoch fehl, da wir keine implizite Umwandlung durchführen können Ausnahme Zu ExType.Wir können es auch nicht explizit konvertieren, wie zum Beispiel:

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = (ExType)(new Exception(message));
        return ex;
    }

Da auch das fehlschlägt..Also ist so etwas möglich? Ich habe das starke Gefühl, dass es ganz einfach sein wird, aber ich habe einen harten Tag mit dem alten Noggin, also lassen Sie es ruhiger angehen :P


Aktualisieren

Danke für die Antworten Leute, es sieht so aus, als wäre es nicht ich gewesen vollständig Idiot!;)

OK, also Vegard Und Sam brachte mich an den Punkt, an dem ich den richtigen Typ instanziieren konnte, blieb dann aber offensichtlich hängen, weil der Nachricht param ist nach der Instanziierung schreibgeschützt.

Matt Mit seiner Antwort hat er den Nagel auf den Kopf getroffen. Ich habe es getestet und alles funktioniert einwandfrei.Hier ist der Beispielcode:

    static ExType TestException<ExType>(string message) where ExType:Exception, new ()
    {
        ExType ex = (ExType)Activator.CreateInstance(typeof(ExType), message);
        return ex;
    }

Süß!:) :)

Danke Leute!

War es hilfreich?

Lösung

Man kann es fast so machen:

static void TestException<E>(string message) where E : Exception, new()
{
    var e = new E();
    e.Message = message;
    throw e;
}

Dies lässt sich jedoch nicht kompilieren, da Exception.Message schreibgeschützt ist.Es kann nur durch Übergabe an den Konstruktor zugewiesen werden, und es gibt keine Möglichkeit, einen generischen Typ mit etwas anderem als einem Standardkonstruktor einzuschränken.

Ich denke, Sie müssten Reflection (Activator.CreateInstance) verwenden, um den benutzerdefinierten Ausnahmetyp mit dem Nachrichtenparameter „neu zu machen“, etwa so:

static void TestException<E>(string message) where E : Exception
{
    throw Activator.CreateInstance(typeof(E), message) as E;
}

Bearbeiten Ups, ich habe gerade gemerkt, dass du es willst zurückkehren die Ausnahme, nicht werfen.Es gilt das gleiche Prinzip, daher belasse ich meine Antwort bei den throw-Anweisungen unverändert.

Andere Tipps

Das einzige Problem bei der Lösung besteht darin, dass es möglich ist, eine Unterklasse von Exception zu erstellen, die keinen Konstruktor mit einem einzelnen String-Parameter implementiert, sodass möglicherweise die MethodMissingException ausgelöst wird.

static void TestException<E>(string message) where E : Exception, new()
{
    try 
    {
      return Activator.CreateInstance(typeof(E), message) as E;
    } 
    catch(MissingMethodException ex) 
    {
      return new E();
    }
}

Ich habe die Art der Ausnahme, die ich auslösen möchte, inline instanziiert, etwa so:

if (ItemNameIsValid(ItemName, out errorMessage))
    throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
    throw new ArgumentNullException("MyArgument is null");

Haben Sie es stattdessen versucht:

static T TestException<Exception>(string message)
{}

weil ich das Gefühl habe, dass die Einführung der generischen Einschränkung nicht wie bei allen auslösbaren Ausnahmen notwendig ist muss sowieso von System.Exception erben.

Denken Sie daran, dass Generika geerbte Typen akzeptieren.

Ich denke, da alle Ausnahmen einen parameterlosen Konstruktor haben sollten, und zwar über den Message Eigenschaft, daher sollte Folgendes funktionieren:

static ExType TestException<ExType>(string message) where ExType:Exception
{
    ExType ex = new ExType();
    ex.Message = message;
    return ex;
}

Bearbeiten:OK, Message ist schreibgeschützt, Sie müssen also hoffen, dass die Klasse stattdessen den Exception(string)-Konstruktor implementiert.

static ExType TestException<ExType>(string message) where ExType:Exception
{
    return new ExType(message);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top