In the following code, I pass a struct into a constructor that is expecting a class. Why does this compile and run without error (and produce the desired output)?
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; }
}
If I change my Main()
method so that it includes a call to ClearEntity()
, as shown below, it still generates no error. Why?
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();
}
where TEntity : class
forces TEntity
to be a reference type, but an interface such as IEntity
is a reference type.
See here: http://msdn.microsoft.com/en-us/library/d5x73970(v=vs.80).aspx
where T : class | The type argument must be a reference type, including any class, interface, delegate, or array type
Regarding your second question, you might think t.ClearEntity()
would fail because it's assigning null to a variable whose type is a value type, but that's not the case. The compile-time type of Entity
is the reference type IEntity
, and the runtime type (after assignment) is the null type. So you never have a variable of type Foo
but value null
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With