2014-03-07 14 views
10

Ich habe eine Schnittstelle:Generics wobei T implementierende Klasse Schnittstelle

interface IProfile { ... } 

... und eine Klasse:

[Serializable] 
class Profile : IProfile 
{ 
    private Profile() 
    { ... } //private to ensure only xmlserializer creates instances 
} 

... und einen Manager mit Methode:

class ProfileManager 
{ 
    public T Load<T>(string profileName) where T : class, IProfile 
    { 
    using(var stream = new .......) 
    { 
     var ser = new XmlSerializer(typeof(T)); 
     return (T)ser.Deserialize(stream); 
    } 
    } 
} 

Ich erwarte, dass die Methode wie folgt verwendet wird:

... und werfen Zeitfehler auf diese kompilieren:

var profile = myManager.Load<IProfile>("TestProfile"); // NO! IProfile interface entered! 

jedoch alles kompiliert und nur Laufzeitfehler wird durch die XmlSerializer geworfen.

Ich dachte, die where T : class würde sicherstellen, nur Klassen-Typen, wo akzeptiert?

Ist es möglich, den Compiler-Fehler zu werfen, wenn IProfile (oder andere Schnittstellen, die von IProfile erben) eingegeben wird, und nur Klassen akzeptiert werden, die IProfile implementieren?

+0

welche Fehler ausgelöst durch 'XmlSerializer'? – Default

+1

@Default das ist egal. Das Problem hierbei ist, dass "T" eine Schnittstelle sein kann, obwohl es eine "Klassen" -Bedingung gibt. – Stijn

+0

@Default: InvalidOperationException {"IProfile kann nicht serialisiert werden, da kein parameterloser Konstruktor vorhanden ist"} – Anders

Antwort

19

Laut Klasse MSDN bedeutet Klasse, dass T ein Referenztyp sein muss; Dies gilt auch für alle Klassen, Schnittstellen, Delegaten oder Array-Typen.

Eine Arbeit um wäre zu verlangen, dass T der Parameter weniger Konstruktor so implementiert:

where T : class, IProfile, new() 
+2

Ja, ich dachte daran, außer dass C# den Konstruktor öffentlich machen möchte. :( – Anders

+0

@Nautious Die einzige andere Möglichkeit kann Code Contracts sein –

+0

Vielleicht eine andere Möglichkeit ist, eine abstrakte Basisklasse zu erstellen und die Einschränkung auf die Basisklasse anstelle der Schnittstelle setzen? – Stijn

Verwandte Themen