C # Generics Casting

Visual sutdio 2008 has the ability to automatically create unit test stubs. I used this to create basic unit tests, but something bothers me:

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 am I getting "Error: cannot convert type" StorageUnitTests.FileStoreTest.bla "to" T "when T is of type" bla "?

I know that "bla" is not a good function name, but just an example.

+4
source share
4 answers

why not? (It doesn't make much difference to create an instance of bla inside 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); } 
+4
source

when T is a type of "bla"

Your above condition is true only for the current case, but I can create a class zero

 public class Bla2: BaseStoreItem {... 

Then Bla2 <> bla ... nor Bla2 is derived from bla, so if I try to use

 StoreDataTestHelper<Bla2>(); 

This is wrong, the compiler is smart enough to understand that it will not work in this state, computer languages โ€‹โ€‹are not like English, they are designed to work the same in all conditions. And they are designed so that the rules of the language are correct in all cases. If they are different from each other, you will have chaos discovering where the error is.

+1
source

Because if T is DerivedStoreItem (inheriting from BaseStoreItem ), you will violate the FileStore<T> , while retaining BaseStoreItem .

0
source

It makes sense. T: BaseStoreItem specifying T: BaseStoreItem , you guaranteed that T will be a type that has BaseStoreItem as a base class, and NOT that it will necessarily be BaseStoreItem . Therefore, if T will later be set as some type to be obtained from BaseStoreItem , your string is target.StoreData(data); will perform an illegal operation.

Although in your case you only StoreDataTestHelper with T set to bla , C # typechecker should make sure that the code for StoreDataTestHelper is safe for the type as a whole. This is one of the advantages of a strongly typed language: it catches possible input errors before you create them.

0
source

Source: https://habr.com/ru/post/1305196/


All Articles