C# 泛型转换

4

Visual Studio 2008具有自动创建单元测试存根的功能。我已经使用它来创建一些基本的单元测试,但是有点困惑:

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

为什么当T的类型为"bla"时,我会得到"Error: Cannot convert type 'StorageUnitTests.FileStoreTest.bla' to 'T'"错误信息?
我知道"bla"不是一个好的函数名,但这只是一个例子。
4个回答

4
为什么不这样做呢? 如果你可以访问T,那么在StoreDataTestHelper内创建bla实例就没有太多意义了。
 public void StoreDataTestHelper<T>() where T : BaseStoreItem, new()
 {
     FileStore<T> target = new FileStore<T>(); 

     T data = new T();

     target.StoreData(data);
 }

@Akash 为什么?Activator.CreateInstance使用反射,速度较慢。我认为new T()更加优雅。 - gsharp
gsharp,抱歉我在问题中错过了您代码中的new()约束,因为没有指定new()。 - Akash Kava
我以前不知道关于 "new()" 这一点。谢谢 gsharp :) - Nippysaurus

1
当T是类型“bla”时,您上述的条件仅适用于当前情况,但我可以创建另一个类。
public class Bla2: BaseStoreItem {...

然后Bla2 <> bla ... ,Bla2也不是从bla派生出来的,所以如果我尝试使用它

StoreDataTestHelper<Bla2>(); 

这是错误的,编译器足够聪明,能够理解在这种情况下它不会工作,计算机语言不像英语,它们被创建为在所有条件下完全相同地工作。它们被设计成语言规则在所有情况下都是正确的。如果它们不同,你将会在找到错误的位置时陷入混乱。


0

因为,如果T是继承自BaseStoreItemDerivedStoreItem,那么存储一个BaseStoreItem就会违反FileStore<T>的类型。


0

这很有道理。通过指定 T: BaseStoreItem,您已经保证了 T 将是一个具有 BaseStoreItem 作为基类的类型,而不一定是一个 BaseStoreItem。因此,如果 T 后来被设置为某个派生自 BaseStoreItem 的类型,那么您的 target.StoreData(data); 行将执行非法操作。

虽然在您的情况下,您只使用 T 设置为 bla 调用 StoreDataTestHelper,但 C# 的类型检查器需要确保 StoreDataTestHelper 的代码在一般情况下是类型安全的。这是强类型语言的好处之一:它可以在您犯错之前捕获潜在的类型错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接