web-dev-qa-db-de.com

Generics, bei denen T eine Klasse implementierende Schnittstelle ist

Ich habe eine Schnittstelle:

interface IProfile { ... }

... und eine Klasse:

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

... und ein 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 so verwendet wird:

var profile = myManager.Load<Profile>("TestProfile"); // class implementing IProfile as T

... und wirft einen Kompilierzeitfehler auf:

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

Es wird jedoch alles kompiliert, und nur der Laufzeitfehler wird von XmlSerializerausgegeben.

Ich dachte, der where T : class würde nur die akzeptierten Klassentypen sicherstellen?

Ist es möglich, den Compiler-Wurffehler zu veranlassen, wenn IProfile(oder andere Schnittstellen, die von IProfileerben) eingegeben wird, und nur Typklassen akzeptiert werden, die IProfileimplementieren?

14
Anders

Gemäß MSDN class bedeutet, dass T ein Referenztyp sein muss; Dies gilt auch für Klassen, Schnittstellen, Delegaten oder Array-Typen.

Um dies zu umgehen, müsste T den parameterlosen Konstruktor so implementieren:

where T : class, IProfile, new()
23
Bob Vale

Funktioniert bei mir

public interface IUser
{
    int AthleteId { get; set; }
    string GivenName { get; set; }
    string FamilyName { get; set; }         
    bool IsActive { get; set; }
}

public  class DjsNameAutoSearch<Result, User> : where User : class, IUser, new()
0
David Jones