web-dev-qa-db-fra.com

Génériques où T est une interface d'implémentation de classe

J'ai une interface:

interface IProfile { ... }

... et une classe:

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

... et un manager avec méthode:

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);
    }
  }
}

Je m'attends à ce que la méthode soit utilisée comme ceci:

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

... et jette l'erreur de temps de compilation sur ceci:

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

Cependant, tout est compilé, et seules les erreurs d'exécution sont générées par la variable XmlSerializer.

Je pensais que le where T : class garantirait que seuls les types de classe étaient acceptés?

Est-il possible de provoquer une erreur de projection du compilateur si IProfile (ou d'autres interfaces héritant de IProfile) est entré et que seules les classes de types implémentant IProfile sont acceptées?

14
Anders

Selon MSDN class signifie que T doit être un type de référence; cela s'applique également à tout type de classe, d'interface, de délégué ou de tableau.

Un contournement consisterait à exiger que T implémente le paramètre less moins constructeur de la manière suivante:

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

Travaille pour moi

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