2

我在我的项目中添加了一个匿名类型:

'Put the courses from the XML file in an Anonymous Type
Dim courses = From myCourse In xDoc.Descendants("Course")
              Select New With
                  {
                      .StateCode = myCourse.Element("StateCode").Value, _
                      .Description = myCourse.Element("Description").Value, _
                      .ShortName = myCourse.Element("ShortName").Value, _
                      .LongName = myCourse.Element("LongName").Value, _
                      .Type = myCourse.Element("Type").Value, _
                      .CipCode = CType(myCourse.Element("CIPCode"), String) _
                }

For Each course In courses
    If Not UpdateSDECourseCode(acadYear, course.StateCode, course.Description, course.Type, course.ShortName, course.LongName, course.CipCode) Then errors.Add(String.Format("Cannot import State Course Number {0} with Year {1} ", course.StateCode, acadYear))
Next

这样做之后,单元测试失败了:

Public Function GetAreaTypeList() As List(Of Type)
    Dim types As New List(Of Type)
    Dim asmPath As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "My.Stuff.dll")

    For Each t As Type In Reflection.Assembly.LoadFrom(asmPath).GetTypes()
        If t.Namespace.StartsWith("My.Stuff.BatchUpdater") Then
            If t.BaseType Is GetType(My.Stuff.BatchUpdater.Area) Then
                types.Add(t)
            End If
        End If
    Next

    Return types
End Function

它失败是因为项目中添加了一个新类型 ( VB$AnonymousType_0`6 ),并且它没有名为Namespace的属性。

我通过对 IF 语句进行以下更改来修复:

If Not t.Namespace Is Nothing AndAlso t.Namespace.StartsWith("My.Stuff.BatchUpdater") Then

由于我不完全了解发生了什么,我对我的代码更改感到怀疑。

为什么匿名类型的命名空间没有?

你会以同样的方式修复你的单元测试吗?或者它应该更具体(例如 If Not t.Names = "VB$AnonymousType_0`6"


更新

decyclone 为我提供了创建更好测试所需的信息:

For Each t As Type In Reflection.Assembly.LoadFrom(asmPath).GetTypes()
    'Ignore CompilerGeneratedAttributes (e.g. Anonymous Types)
    Dim isCompilerGeneratedAttribute = t.GetCustomAttributes(False).Contains(New System.Runtime.CompilerServices.CompilerGeneratedAttribute())

    If Not isCompilerGeneratedAttribute AndAlso t.Namespace.StartsWith("My.Stuff.BatchUpdater") Then
         '...Do some things here
    End If
Next

老实说,它可以通过 LINQ 查询得到更多改进,但这适合我。

4

1 回答 1

1

匿名方法和类型用CompilerGeneratedAttribute修饰。您可以检查它们的存在以识别匿名类型。

var anonymous = new { value = 1 };

Type anonymousType = anonymous.GetType();
var attributes = anonymousType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);

if (attributes.Any())
{
    // Anonymous
}

您可以在测试中过滤掉这些。

也可以使用CompilerGeneratedAttribute标记用户定义的类型。所以也许你可以将它与检查命名空间是否为空结合起来

var anonymous = new { value = 1 };

Type anonymousType = anonymous.GetType();
var attributes = anonymousType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);

if (attributes.Any() && anonymousType.Namespace == null)
{
    // Anonymous
}
于 2012-08-20T15:44:29.513 回答