是"T:class"在编译时或运行时是否以任何方式强制执行?

dev*_*xer 6 c# generics struct class

在下面的代码中,我将一个struct传递给一个期望一个类的构造函数.为什么编译运行没有错误(并产生所需的输出)?

class Program
{
    static void Main()
    {
        var entity = new Foo { Id = 3 };
        var t = new Test<IEntity>(entity); // why doesn't this fail?
        Console.WriteLine(t.Entity.Id.ToString());
        Console.ReadKey();
    }
}

public class Test<TEntity> where TEntity : class
{
    public TEntity Entity { get; set; }

    public Test(TEntity entity)
    {
        Entity = entity;
    }

    public void ClearEntity()
    {
        Entity = null;
    }
}

public struct Foo : IEntity
{
    public int Id { get; set; }
}

public interface IEntity
{
    int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果我改变我的Main()方法以便它包含一个调用ClearEntity(),如下所示,它仍然不会产生错误.为什么?

static void Main()
{
    var entity = new Foo { Id = 3 };
    var t = new Test<IEntity>(entity);
    Console.WriteLine(t.Entity.Id.ToString());
    t.ClearEntity(); // why doesn't this fail?
    Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*man 8

where TEntity : classforce TEntity是一个引用类型,但是一个接口,例如IEntity引用类型.

请看:http: //msdn.microsoft.com/en-us/library/d5x73970(v = vs.80).aspx

其中T:class | type参数必须是引用类型,包括任何类,接口,委托或数组类型

关于你的第二个问题,你可能认为t.ClearEntity()会失败,因为它为类型为值类型的变量赋值null,但事实并非如此.编译时类型Entity是引用类型IEntity,运行时类型(赋值后)是null类型.所以你永远不会有类型的变量Foo而是值null.