简体   繁体   中英

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
     {
     //
     }

  /// <summary>
  ///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.

因为,如果TDerivedStoreItem (继承BaseStoreItem ),则会通过存储BaseStoreItem来违反FileStore<T>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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM