vb.net - 是否可以在 VB.NET 中的通用接口集合上实现扩展方法?
问题描述
我无法编写可以从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
推荐阅读
- python - Python Django - 内部错误 ProgrammingError 关系不存在
- javascript - 除非页面刷新,否则 React 路由器会更改 url 但不会查看
- flutter - 可以直接用 Flutter 内置的 Canvas 绘制方法来渲染变宽笔画吗?
- python - 如何设置正确的循环
- django - ModuleNotFoundError:没有名为“survey_responses”的模块
- python - Plotly python histogram 将自定义颜色添加到不同的值
- typescript - “Vue”类型上不存在属性“x”
- html - HTML:单击时未下载文件
- django - Web 应用程序的 GDPR 合规性(Vue.js、Django、Heroku)
- python - 在 Windows 上安装 psycopg2 时 KeyError = "static"