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