C# Generics Casting
Visual Studio 2008 has the ability to automatically create unit test stubs. I have used this to create some basic unit tests, but I am confused by something:
private class bla : BaseStoreItem
{
//
}
/// <summar开发者_如何学运维y>
///A test for StoreData
///</summary>
public void StoreDataTestHelper<T>() where T : BaseStoreItem
{
FileStore<T> target = new FileStore<T>(); // TODO: Initialize to an appropriate value
BaseStoreItem data = new bla();
target.StoreData(data);
}
[TestMethod()]
public void StoreDataTest()
{
//Assert.Inconclusive("No appropriate type parameter is found to satisfies the type constraint(s) of T. " +
// "Please call StoreDataTestHelper<T>() with appropriate type parameters.");
StoreDataTestHelper<bla>();
}
Why do I get "Error: Cannot convert type 'StorageUnitTests.FileStoreTest.bla' to 'T'" when T is type "bla"?
I know "bla" is not a good function name, but its just an example.
why not that way? (It doesn't make much sence to create an instance of bla inside of StoreDataTestHelper if you have access to T)
public void StoreDataTestHelper<T>() where T : BaseStoreItem, new()
{
FileStore<T> target = new FileStore<T>();
T data = new T();
target.StoreData(data);
}
when T is type "bla"
Your above condition holds true only for current case, but I can create a nother class
public class Bla2: BaseStoreItem {...
Then Bla2 <> bla ... , neither Bla2 is derived from bla, so if I try to use
StoreDataTestHelper<Bla2>();
This is wrong, compiler is smart enough to understand that in this condition it will not work, computer languages are not like english, they are created to work exactly same in all conditions. And they are designed so that rules of language are correct in all cases. If they differ you will have chaos finding where the error is.
Because, if T
is DerivedStoreItem
(inheriting BaseStoreItem
), you would be violating the type of FileStore<T>
by storing a BaseStoreItem
.
This makes sense. By specifying T: BaseStoreItem
, you have guaranteed that T
will be a type the has BaseStoreItem
as a base class, and NOT that it will necessarily be a BaseStoreItem
. Therefore, if T is later set to be some type that derives from BaseStoreItem
, your target.StoreData(data);
line would be performing an illegal operation.
Although in your case you only invoke StoreDataTestHelper
with T
set to bla
, C#'s typechecker needs to make sure that the code for StoreDataTestHelper
is type-safe in general. This is one of benefits to a strongly-typed language: it catches potential typing mistakes before you make them.
精彩评论