请考虑以下代码:
public class SystemManager<T> where T : ISettings
{
public SystemManager()
{
T implicit1 = default(T);
T implicit2 = default(T);
if (implicit1 != implicit2)
{
// This will not compile saying the compiler cannot compare
// using '!=' two objects of type 'T' and 'T'
}
ISettings explicit1 = null;
ISettings explicit2 = null;
if (explicit1 != explicit2)
{
// This will compile fine
}
}
}
在上面,编译器知道T 是 ISettings,那么为什么比较只能在泛型范围之外?这会是“.NET 4是答案”之一吗?
修改
在回答Manu的问题时,为什么直接使用泛型而不是ISettings。
假设以下内容:
void Main()
{
SystemManager<XmlSettings> manager = new SystemManager<XmlSettings>();
// I want to disallow the following
SystemManager<RegistrySettings> manager = new SystemManager<RegistrySettings>();
}
public interface ISettings
{
}
public class XmlSettings : ISettings, IDisposable
{
public void Dispose() { }
}
public class RegistrySettings : ISettings
{
}
这样我就不允许任何不实现IDisposable的ISettings实现。例如,我无法控制ISettings并且无法使其他类实现ISettingsDisposable类。
显然,Disposable是一个例子,但是你可以把任何东西放在那里 - 这个想法是我可能想要比ISettings更严格地限制。
编辑2:
回应关于结构不能==能够的要点:
public struct StructSettings : ISettings
{
}
我可以执行上述操作并实现SystemManager的通用StructSettings
版本:
然后,在SystemManager中,我可以比较两个结构,没有运行时错误。
SystemManager<StructSettings> manager = new SystemManager<StructSettings>();
这样可行,并且SystemManager构造函数中的结构上的==不会抛出任何运行时错误。
答案 0 :(得分:2)
有趣:我认为它与编译器有关,不知道T是引用还是值类型,因为如果你添加约束T:class-它编译得很好。
比较的语义是比较引用是否相等。
答案 1 :(得分:2)
显然,运算符==未在结构中实现。这就是为什么如果你把T:class,它会起作用。
该文件的链接,以便我们可以看到您说的工作版本会很棒:)。或者只是编辑你的帖子。