Search code examples
.netvb.netwinformslambdataglib-sharp

Issue trying to use a Lambda expression


I want to code a generic function to set a tag field of a music file, I'm using "TagLib Sharp" library, I'm trying to code something that can be tittled as "TagLib Sharp Helper Class"

To call the procedure I want to use some syntax like this to set the field "Album":

 TagLibSharp.Set_Tag_And_Save( _
             "C:\Test.mp3", _
             Function() TagLib.File.Create("").Tag.Album, _
             "Test album name" _
 )

The problem is I don't know what to do with the Lambda expression inside the procedure...

Here is all the code (notice the comment lines explainning where is the problem):

#Region " TagLib Sharp "

Public Class TagLibSharp

''' <summary>
''' Stores the Taglib object.
''' </summary>
Private Shared TagFile As TagLib.File = Nothing

''' <summary>
''' Sets a Tag field and saves the file changes.
''' </summary>
Public Shared Sub Set_Tag_And_Save(ByVal File As String, _
                                   ByVal Field As Linq.Expressions.Expression(Of Func(Of Object)), _
                                   ByVal Value As String)

    TagFile = TagLib.File.Create(File)

    Dim member As Linq.Expressions.MemberExpression = _
        If(TypeOf Field.Body Is Linq.Expressions.UnaryExpression, _
           DirectCast(DirectCast(Field.Body, Linq.Expressions.UnaryExpression).Operand, Linq.Expressions.MemberExpression), _
           DirectCast(Field.Body, Linq.Expressions.MemberExpression))

    MsgBox(member.Member.Name) ' Result: "Album"

    ' member.Member = Value ' Here is where I don't know what to do
    '
    ' This would be the ewuivalent:
    TagFile.Tag.Album = Value

    TagFile.Save()

End Sub

End Class

#End Region

UPDATE

Trying to solve the problem following the steps of Ben Allred solution I get an exception.

TagLibSharp.Set_Tag_And_Save("c:\1.mp3", Function() TagLib.File.Create("").Tag.Album = "Test album name")

The modified sub:

Public Shared Sub Set_Tag_And_Save(ByVal File As String, _
                                   ByVal FieldSetter As Action(Of TagLib.File))

    TagFile = TagLib.File.Create(File)
    FieldSetter(TagFile) ' Here throws an exception with this message: "taglib/"
    ' FieldSetter(TagLib.File.Create(File)) ' The same exception with this one.
    TagFile.Save()

End Sub

UPDATE 2:

Now I don't get any exception, but the tag field is not set.

TagLibSharp.Set_Tag_And_Save("c:\Test.mp3", Function(tagLibFile) tagLibFile.Tag.Title = "Test title name")

The modified sub:

Public Shared Sub Set_Tag_And_Save(ByVal File As String, _
                                   ByVal FieldSetter As Action(Of TagLib.File))

    TagFile = TagLib.File.Create(File)

    MsgBox(TagFile.Tag.Title) ' Result: Unbreakeable
    FieldSetter(TagFile)
    MsgBox(TagFile.Tag.Title) ' Result: Unbreakeable

    ' TagFile.Tag.Title = "Test title name"
    ' MsgBox(TagFile.Tag.Title) ' Result: "Test title name"

    TagFile.Save()

End Sub

Solution

  • (My syntax is C#. I don't know the exact syntax in VB.)

    The easiest way to do what you want with what you have is to make the following changes:

    1 - Change the lambda expression to take one parameter of type TagLib.File.

    public void Set_Tag_And_Save(..., Action<TagLib.File> FieldSetter, ...)
    

    2 - Pass the action to the call to Set_Tag_And_Save and set the value in the action.

    Set_Tag_And_Save("C:\Test.mp3", tagLibFile => tagLibFile.Tag.Album = "Test album name");
    

    3 - Call the action inside Set_Tag_And_Save.

    FieldSetter(TagFile);
    TagFile.Save();