繁体   English   中英

如何将泛型类型转换为另一种类型?

[英]how to cast a generic type to another type?

如显示的第一个类所示,我需要将 Activité 强制转换为 Réunion(Réunion extends Activité),但编译器告诉我不能。 为什么? 我将制定一个计划,以便您可以更好地了解我的课程结构以及我所有的其他课程。 谢谢你。

class Employé<T>
{
    private string nom;
    private Local bureau;
    private LinkedList<Activité<T>> activités;

    public Employé(string nom, Local bureau)
    {
        this.nom = nom;
        this.bureau = bureau;
    }

    public void AjouteActivité(params Activité<T>[] activités)
    {
        foreach(Activité<T> activité in activités)
        {
            if (activité as Réunion != null)
                // here's the problem !!! ((Réunion)activité).EmployéConvoqués = activité;
        }
    }
}

这是我的类结构的方案:

这是其他类:

abstract class Activité<T>
{
    private string label;
    private DateTime début, fin;
    private T lieu;
    private readonly int id;
    private static int CPT = 0;

    public Activité(string label, DateTime début, DateTime fin, T lieu)
    {
        this.label = label;
        this.début = début;
        this.fin = fin;
        this.lieu = lieu;
        this.id = ++CPT;
    }

    public override string ToString()
    {
        return $"{id} : {label}(de {début} à {fin}) - {DescriptionLieu()}";
    }

    public double Duree()
    {
        return fin.Subtract(début).TotalMinutes;
    }

    public int Id
    {
        //tester get; seulement
        get
        {
            return id;
        }
    }

    public T Lieu
    {
        get
        {
            return lieu;
        }
    }

    public abstract string DescriptionLieu();
}
class ActivitéExtérieure : Activité<string>
{
    public ActivitéExtérieure(string label, DateTime début, DateTime fin, string lieu) : base(label,début,fin,lieu) { }

    public override string DescriptionLieu()
    {
        return Lieu;
    }
}
class ActivitéInterne : Activité<Local>
{
    public ActivitéInterne(string label, DateTime début, DateTime fin, Local lieu) : base(label,début,fin,lieu)
    {
        lieu.AjouteActivité(this);
    }

    public override string DescriptionLieu()
    {
        return $"local :: {Lieu.NumComplet}";
    }
}
class Employé<T>
{
    private string nom;
    private Local bureau;
    private LinkedList<Activité<T>> activités;

    public Employé(string nom, Local bureau)
    {
        this.nom = nom;
        this.bureau = bureau;
    }

    public void AjouteActivité(params Activité<T>[] activités)
    {
        foreach(Activité<T> activité in activités)
        {
            if (activité as Réunion != null)
                ((Réunion)activité).EmployéConvoqués = activité;
        }
    }
}
class Local
{
    private int etage;
    private int numero;
    private bool possedeWifi;
    private Dictionary<int, ActivitéInterne> historiquesActivités;

    public int Numero
    {
        get
        {
            return numero;
        }
        set
        {
            if (value < 0 || value > 99)
                throw new IndexOutOfRangeException();
            else
                numero = value;
        }
    }

    public int NumComplet
    {
        get
        {
            return etage * 100 + numero;
        }
    }

    public bool PossedeWifi
    {
        get
        {
            return possedeWifi;
        }
    }

    public Local(int etage, bool possedeWifi, int numero)
    {
        this.etage = etage;
        this.possedeWifi = possedeWifi;
        Numero = numero;
    }

    public Local(int etage, int numero) : this(etage, true, numero) { }

    public Local(int local, bool possedeWifi) : this(local / 100, possedeWifi, local % 100) { }

    public void AjouteActivité(ActivitéInterne a)
    {
        historiquesActivités.Add(a.Id, a);
    }
}
class Réunion : ActivitéInterne
{
   private HashSet<Employé<Local>> employésConvoqués;
   public Réunion(string label, DateTime début, DateTime fin, Local lieu) : base(label, début, fin, lieu) { }

   public Employé<Local> EmployéConvoqués
   {
        set
        {
            employésConvoqués.Add(value);
        }
   }
}

错误消息说“演员是多余的”。 这是因为您已经测试了“activité as Réunion != null”。 编译器发现在“if”子句中这个条件已经为真,因此转换没有意义。 另一方面,您无法访问 activité.EmployéConvoqués,因为活动的静态类型不是 Réunion。

您所要做的就是在测试类型时引入一个新变量。 像这样:

if (activité is Réunion réunion) {
    réunion.EmployéConvoqués = activité;    
}

但是,如果您尝试此操作,您将看到无法完成分配,因为您正在尝试将活动分配给 Employé<Local>。 这些不是兼容的类型。 也许你的意思是

        foreach (Activité<T> activité in activités) {
            if (activité is Réunion réunion && this is Employé<Local> employéLocal) {
                réunion.EmployéConvoqués = employéLocal;
            }
        }

注释:在 Réunion 的定义中,当设置属性 Employé<Local> EmployéConvoqués 时,您将添加到 HashSet<Employé<Local>>employésConvoqués。 从样式的角度来看,这很奇怪,因为人们通常期望 Employé<Local> 类型的属性代表单个 Employé<Local> 而不是 Employé<Local> 的集合。 我建议你删除二传手,而是定义

    public void Ajoute( Employé<Local> employéConvoqué) {
         this.employésConvoqués.Add(employéConvoqué);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM