C# 在集合中使用接口约束时是否可以访问属性?

C# 在集合中使用接口约束时是否可以访问属性?,c#,collections,interface,constraints,C#,Collections,Interface,Constraints,我真正想了解的是,当使用接口作为泛型类的约束时,为什么我能够访问在实现该接口的类中定义的“Nume”属性。我的问题是: 为什么我必须在泛型类中添加接口作为约束,而我已经在初始Tr类中实现了它 为什么我不能直接从类访问属性,为什么我可以通过实现接口来访问属性 如果没有接口,我无法从Tr类访问属性,因此我实现了Stackoverflow问题的解决方案,它似乎可以工作,但我无法确切理解原因 我还看了微软的文档 interface GET { int Nume { get; } }

我真正想了解的是,当使用接口作为泛型类的约束时,为什么我能够访问在实现该接口的类中定义的“Nume”属性。我的问题是:

  • 为什么我必须在泛型类中添加接口作为约束,而我已经在初始Tr类中实现了它
  • 为什么我不能直接从类访问属性,为什么我可以通过实现接口来访问属性
如果没有接口,我无法从Tr类访问属性,因此我实现了Stackoverflow问题的解决方案,它似乎可以工作,但我无法确切理解原因

我还看了微软的文档

interface GET
{
    int Nume { get; }
}

class Tr : GET 
{
    public int Nume { get; }

    public Tr() { }

    public Tr(int num)
    {
        this.Nume = num;
    }
}

class Program<Tr> where Tr : GET
{
   static List<Tr> lst = new List<Tr>();

    public void Test(Tr merge)
    {           
        lst.Add(merge);
        foreach (Tr cadt in lst)
        {
            Console.WriteLine($"Numarul este {cadt.Nume}");
        }
    }     
}

class MainC
{      
    static void Main(string[] args)
    {
        Tr cc = new Tr(2);

        Program<Tr> cls = new Program<Tr>();
        cls.Test(cc);
    }        
}
接口获取
{
int Nume{get;}
}
类Tr:获取
{
公共整数{get;}
公共Tr(){}
公共Tr(整数)
{
this.Nume=num;
}
}
Tr:GET所在的类程序
{
静态列表lst=新列表();
公共无效测试(Tr合并)
{           
添加(合并);
foreach(第一层中的Tr cadt)
{
Console.WriteLine($“Numarul este{cadt.Nume}”);
}
}     
}
MainC类
{      
静态void Main(字符串[]参数)
{
Tr cc=新的Tr(2);
程序cls=新程序();
cls试验(cc);
}        
}
我原以为这段代码在没有界面帮助的情况下可以工作,但它崩溃了。它在界面的帮助下工作。

类程序中,Tr:GET
Tr
类型参数,它只是一个名称,与
Tr
没有任何关系。因此它实现
GET
,它也不提供
Nume
属性。但是如果你把约束条件
放在Tr:GET
的地方,情况就会改变。现在它实现了
GET
,并且提供了
Nume
属性

您的班级相当于:

class Program<T> where T : GET
{
    static List<T> lst = new List<T>();

    public void Test(T merge)
    {
        lst.Add(merge);
        foreach (T cadt in lst)
        {
            Console.WriteLine($"Numarul este {cadt.Nume}");
        }
    }
}
类程序,其中T:GET
{
静态列表lst=新列表();
公共无效测试(T合并)
{
添加(合并);
foreach(第一层中的T cadt)
{
Console.WriteLine($“Numarul este{cadt.Nume}”);
}
}
}
这就是原因

  • 必须将接口作为约束添加到泛型类中
  • 不能直接从类访问属性
  • 您可以通过实现接口来访问它
使用
会造成混乱。如果我是一名编译器开发人员,我会将其视为一个错误(至少是一个警告),我不会让这样的代码编译

下面是
课程中
的一个示例程序
不是
Tr
课程。

“但它崩溃了”没有帮助,确切的错误是什么?在你的问题中包含信息。您发布的代码运行时没有错误,我们需要更多信息。@训练频道,正如我从问题中了解到的,错误在那里没有
where Tr:GET
约束,您必须添加它来修复错误。是吗?@Alex是的。我使用了stackoverflow链接中提供的解决方案,但我之所以发布这个问题,希望有人能解释为什么通过实现该接口,代码起了作用。@Workout Channel,请参阅我答案的更新。它给出了所有的解释。谢谢@Alex。因此,从我的理解来看:只是一个类型参数,它与实际的Tr类无关,可以被任何东西替换。编译器知道Nume属性,因为类型参数实现了定义Nume属性的接口,所以to编译器现在知道将替换的对象必须包含Nume属性。如果我错了,请纠正我。当它甚至不完整时,你怎么可能回答这个问题?发布的代码运行时没有错误。@DavidG,正如我从问题中得到的,错误在那里没有
约束,OP必须添加它来修复错误。