2 votes

Assistance nécessaire avec les types génériques - le type ne peut pas être utilisé comme paramètre de type

J'ai rencontré un léger problème avec la conception de ma classe et j'ai du mal à le résoudre. Après avoir cherché sur le web en vain, j'espère que quelqu'un ici aura la gentillesse de m'indiquer la bonne direction. J'ai posté l'intégralité du code, donc en théorie, je devrais être capable de faire un simple copier-coller dans VS et de visualiser l'erreur.

Merci d'avance, Onam.

Erreur complète : Le type 'Complainant' ne peut pas être utilisé comme paramètre de type 'T' dans le type générique ou la méthode 'Person'. Il n'y a pas de conversion implicite de référence de 'Complainant' à 'ObjectFactory'.

#region : Complainant :
public class Complainant : Person<Complainant>
{
    #region Properties...

    #region ComplainantId
    public Int64 ComplainantId { get; private set; }
    #endregion

    #region IsApproachable
    public bool IsApproachable { get; set; }
    #endregion

    #endregion

    #region Constructors...
    public Complainant()
    {
    }
    #endregion

    #region Methods...

    #region Load
    public void Load(Int64 objectId)
    {
        base.Hydrate(objectId);
    }
    #endregion

    #endregion
}
#endregion

#region : Person :
public class Person<T> : ObjectFactory<T>
{
    #region Properties...

    #region PersonId
    public Int64 PersonId { get; protected set; }
    #endregion

    #region DOB
    public DateTime DOB { get; set; }
    #endregion

    #region Email
    public string Email { get; set; }
    #endregion

    #region Forename
    public string Forename { get; set; }
    #endregion

    #region Fullname
    public string Fullname { get { return Forename + " " + Surname; } }
    #endregion

    #region HomeTel
    public string HomeTel { get; set; }
    #endregion

    #region Initials
    public string Initials { get; set; }
    #endregion

    #region Mobile
    public string Mobile { get; set; }
    #endregion

    #region Surname
    public string Surname { get; set; }
    #endregion

    #region WorkTel
    public string WorkTel { get; set; }
    #endregion

    #endregion

    #region Constructor
    public Person()
    {
    }
    #endregion
}
#endregion

#region : Property :
public class Property
{
    #region Properties...

    #region Inherits
    [XmlAttribute("Inherits")]
    public string Inherits { get; set; }
    #endregion

    #region IsPrimaryKey
    [XmlAttribute("IsPrimaryKey")]
    public bool IsPrimaryKey { get; set; }
    #endregion

    #region Name
    [XmlAttribute("Name")]
    public string Name { get; set; }
    #endregion

    #endregion

    #region Constructors...

    public Property(string name, bool isPrimaryKey)
    {
        this.Name = name;
        this.IsPrimaryKey = isPrimaryKey;
    }

    public Property()
    {
    }

    #endregion

    #region Methods

    #endregion
}
#endregion

#region : ObjectFactory :
public class ObjectFactory<T> where T : new()
{
    #region Members...
    static Expression<Func<T>> __x = () => new T();
    static Func<T> __function = __x.Compile();
    static Dictionary<Type, List<Property>> __cache = new Dictionary<Type, List<Property>>();
    #endregion

    #region Constructors
    public ObjectFactory()
    {
        Type _type = typeof(T);

        if (!__cache.ContainsKey(_type))
        {
            __cache.Add(_type, Deserialize(_type.Name));
        }
    }
    #endregion

    #region Methods

    #region Build
    public static T Build()
    {
        return __function();
    }
    #endregion

    #region Deserialize
    private List<Property> Deserialize(string objectName)
    {
        XmlSerializer _serializer = new XmlSerializer(typeof(List<Property>));
        using (Stream _stream = File.OpenRead(String.Format(@"C:\_XMLFiles\{0}.xml", objectName)))
        {
            return (List<Property>)_serializer.Deserialize(_stream);
        }
    }
    #endregion

    #region Hydrate
    protected void Hydrate(Int64 objectId)
    {
        List<Property> _properties = new List<Property>();

        if (__cache.TryGetValue(typeof(T), out _properties))
        {
            object[] o = typeof(T).GetProperties();
            foreach (PropertyInfo pi in typeof(T).GetProperties())
            {
                string s = pi.Name;
                //if (pi.Name == name)
                //{
                    //pi.SetValue(this, value, null);
                //}
            }
        }
    }
    #endregion

    #endregion
}
#endregion

1voto

Samuel Slade Points 3910

Je ne suis pas sûr à 100 % que ce soit la raison, mais vous devriez maintenir les contraintes de paramètres génériques sur les fichiers de type Person<T> classe. Ajoutez donc le where T : new() à la Person<T> classe.

EDIT

Après avoir compilé votre code, j'obtiens l'erreur :

Erreur 1 'T' doit être un type non abstrait avec un constructeur public sans paramètre afin de l'utiliser comme paramètre 'T' dans le type générique ou la méthode 'Reflection.ObjectFactory' SomeClass.cs 67 18 Reflection

Cette erreur est résolue par l'ajout de l'élément where clause que j'ai mentionnée plus haut. Après ce point, je n'obtiens aucune erreur de compilation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X