vb.net - 是否可以在 VB.NET 中的通用接口(interface)集合上实现扩展方法?

标签 vb.net generics constraints

我无法编写可从以下解决方案中 ListOfTests 类型的对象调用的 VB.NET 扩展方法。

我可以使用泛型类型约束在 C# 中编写扩展方法。

这是我编写的一些测试代码,用于演示我在更大的现有 VB.NET 解决方案中遇到的问题。

这里讨论的扩展方法是FilterByIDs,这只是我选择的一个不恰当的例子。

工作 C# 解决方案:

using System;
using System.Collections.Generic;
using System.Linq;

static class TestApp
{
    public static void Main()
    {
        var objTest = new ListOfTests
        {
            new Test {Id = 1}, new Test {Id = 2}, new Test {Id = 3}
        };

        objTest.FilterByIDs(new [] {3});

        // Prints "3" only - Extension method works
        objTest.ForEach(x => Console.WriteLine(x.Id));
    }
}

public static class Extensions
{
    public static void FilterByIDs<T, TID>(this List<T> target, IEnumerable<TID> objIDs) where T : ITest<TID>
    {
        target.RemoveAll(x => !objIDs.Contains(x.Id));
    }
}

public class ListOfTests : List<Test>
{}


public class Test : ITest<int>
{
    public int Id { get; set; }
}

public interface ITest<TID>
{
    TID Id { get; }
}

我尝试在 VB.NET 中编写此内容(未构建):

Imports System.Runtime.CompilerServices

Class TestApp
    Public Shared Sub Main()
        Dim objTest As New ListOfTests()
        objTest.Add(New Test() With { .ID = 1})
        objTest.Add(New Test() With { .ID = 2})
        objTest.Add(New Test() With { .ID = 3})

        objTest.FilterByIDs({3})

        objTest.ForEach(Sub(x) Console.WriteLine(x.ID))
    End Sub
End Class

Public Module Extensions
    <Extension>
    Public Sub FilterByIDs(Of T As ITest(Of TID), TID)(target As List(Of T), objIDs As IEnumerable(Of TID))
        target.RemoveAll(Function(x) Not objIDs.Contains(x.Id))
    End Sub
End Module

Public Class ListOfTests
    Inherits List(Of Test)
End Class

Public Class Test
    Implements ITest(Of Integer)

    Public Property ID As Integer Implements ITest(Of Integer).ID
End Class

Public Interface ITest (Of T)

    Property ID As T
End Interface

VB.NET 解决方案的构建错误是

"TestApp.vb(18, 16): [BC36561] 扩展方法 'FilterByIDs' 具有永远无法满足的类型约束。"

可以用 VB.NET 编写这个吗?

最佳答案

不一样的优雅和编译安全性,但工作:

<Extension>
Public Module Extensions

    <Extension>
    Public Sub FilterByIDs(Of T)(target As IList, objIDs As IEnumerable(Of T))
        If (target Is Nothing) Then Throw New NullReferenceException() 'To simulate instance method behavior
        For i As Int32 = target.Count - 1 To 0 Step -1
            Dim myTest As ITest(Of T) = TryCast(target(i), ITest(Of T))
            If (myTest Is Nothing) Then
                target.RemoveAt(i)
            Else
                If (Not objIDs.Contains(myTest.ID)) Then target.RemoveAt(i)
            End If
        Next
    End Sub

End Module

关于vb.net - 是否可以在 VB.NET 中的通用接口(interface)集合上实现扩展方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56776321/

相关文章:

Java泛型编程: Determining if class extends another

java - 使用泛型实现方法

mysql - 为什么我在单个自引用表的事务中遇到 MySQL 外键插入约束违规?

vb.net 仅限外部的属性或方法

sql-server - 从 Visual Basic API 读取 SQL Server 存储过程

java - 这段处理泛型的 Java 代码有什么问题?

swift - 不等式约束以编程方式快速实现

php - 无法将外键值插入链接表

c# - 如何根据数字是正数还是负数应用不同的格式

asp.net - 当内容更改时如何清除现有的下拉列表项?