2010-03-26 133 views
4

Visual sutdio 2008能够自动创建单元测试存根。我用它来创建一些基本的单元测试,但我的东西迷惑:C#泛型铸造

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>(); 
    } 

为什么我会收到“错误:无法转换类型‘StorageUnitTests.FileStoreTest.bla’到‘T’”当T键入“bla”?

我知道“bla”不是一个好的函数名,但它只是一个例子。

回答

4

为什么不那样呢? (它没有多大SENCE创建StoreDataTestHelper的BLA内的一个实例,如果你有机会到T)

public void StoreDataTestHelper<T>() where T : BaseStoreItem, new() 
{ 
    FileStore<T> target = new FileStore<T>(); 

    T data = new T(); 

    target.StoreData(data); 
} 
+0

我认为它应该是Activator.CreateInstance ()而不是新的T().. – 2010-03-26 10:01:19

+0

@Akash为什么? Activator.CreateInstance使用反射,它很慢。它认为新的T()更优雅。 – gsharp 2010-03-26 10:11:59

+0

gsharp,对不起,我错过了,在你的代码中的new()约束,因为没有指定new() – 2010-03-26 10:19:13

0

因为,如果TDerivedStoreItem(继承BaseStoreItem),您就违反了类型FileStore<T>通过存储BaseStoreItem

0

这是有道理的。通过指定T: BaseStoreItem,您确保T将作为基类的BaseStoreItem类型,而不是它必然是BaseStoreItem。因此,如果T后来被设置为来自BaseStoreItem的某种类型,那么您的target.StoreData(data);行将执行非法操作。

虽然你的情况,你只用T集调用StoreDataTestHelperbla,C#的typechecker需要确保为StoreDataTestHelper的代码是类型安全的一般。这是一种强类型语言的好处之一:在制作它们之前捕获潜在的输入错误。

1

when T is type "bla"

你的上述条件仅适用于当前的情况下也是如此,但我可以创造一个诺特尔类

public class Bla2: BaseStoreItem {... 

然后Bla2 <> BLA ...,既不Bla2从BLA派生,所以如果我尝试使用

StoreDataTestHelper<Bla2>(); 

这是错误的,编译器是足够聪明,明白,在这种情况下它不会工作,计算机语言是不喜欢英语,他们正在创建工作exactl y在所有条件下都相同。而且它们的设计使语言规则在所有情况下都是正确的。如果他们不同,你会发现混乱发现错误的地方。