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でマークすることもできます。したがって、名前空間がnullかどうかのチェックと組み合わせることができるかもしれません

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 に答える