“私有”可见性修饰符 - 将 C# 转换为 VB 时如何处理差异?
Posted
技术标签:
【中文标题】“私有”可见性修饰符 - 将 C# 转换为 VB 时如何处理差异?【英文标题】:"Private" visibility modifier - how to handle differences when converting C# to VB? 【发布时间】:2013-11-13 06:34:45 【问题描述】:背景
我已经使用 DeveloperFusion.com 上的转换器将下面的 C# 代码(在 TreeViewAdv 文件 TreeColumn.cs 中找到)转换为 VB.net 代码。
C#
using System;
//...(other using calls)
namespace Aga.Controls.Tree
[TypeConverter(typeof(TreeColumn.TreeColumnConverter)), DesignTimeVisible(false), ToolboxItem(false)]
public class TreeColumn : Component
private class TreeColumnConverter : ComponentConverter
public TreeColumnConverter()
: base(typeof(TreeColumn))
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
return false;
//…Some, I believe, unrelated code
VB
Imports System.Collections.Generic
‘...(other Imports calls)
Namespace Aga.Controls.Tree
<TypeConverter(GetType(TreeColumn.TreeColumnConverter)), DesignTimeVisible(False), ToolboxItem(False)> _
Public Class TreeColumn
Inherits Component
Private Class TreeColumnConverter
Inherits ComponentConverter
Public Sub New()
MyBase.New(GetType(TreeColumn))
End Sub
Public Overrides Function GetPropertiesSupported(ByVal context As ITypeDescriptorContext) As Boolean
Return False
End Function
End Class
‘...some, I believe, unrelated code
End Class
问题
在这行 C# 代码中访问 TreeColumn.TreeColumnConverter 就可以了。 [TypeConverter(typeof(TreeColumn.TreeColumnConverter)), DesignTimeVisible(false), ToolboxItem(false)]
但是,VB.Net 不允许在转换后的行中访问该成员:
错误描述为:Aga.Controls.Tree.TreeColumn.TreeColumnConverter' is not accessible in this context because it is 'Private'
。但是,在这两种情况下,TreeColumn.TreeColumnConverter 都被声明为 Private。
问题
1.) 为什么。由于这对我来说是一个学习项目,所以我想知道为什么范围在两种语言之间的行为不同。这是他们两个中比较重要的一个问题。
2.) 如何。更改 VB 代码以允许 TreeColumnConverter 访问已识别的代码行而不打开范围以致可能在其他地方造成命名混淆的最佳方法是什么?我可以将其声明为 Public,但我想有一种更正确的方法。
回答时要记住的事项
1.) 我知道在 VB.net 中,私有成员在声明它们的对象之外是不可用的。所以告诉我这不会有帮助,在我看来不是答案。
【问题讨论】:
我不太清楚为什么这需要一个巨大的答案。只需将其从私人更改为朋友。 VB.NET 是一种友好的语言。 @HansPassant 您应该将其发布为答案,虽然您没有给我 WHY,但这是一个有效的 HOW。 Jordao 的回答也是一个有效的方法。如果你能说服我你的方法更好,我会给你“接受的答案”。 【参考方案1】:啊,我相信我看到了你的问题。
这是命名空间。
VB.NET 链接命名空间。
Namespace Aga.Controls.Tree
in vb.net 实际上是您项目的默认命名空间与文件中声明的命名空间连接。
它实际上是Aga.Controls.Tree.Aga.Controls.Tree
,所以它可能无法到达它需要的范围,因为它指向了错误的命名空间。
C#,您完全限定了命名空间... DevFusion 的转换器(与 SharpDevelop IDE 中使用的转换器相同)不知道这一点。
【讨论】:
我确定吗?不......每个人的Visual Studio配置都是废话。我每天都在 VB.NET 和 C# 项目之间来回切换,当我必须将一个转换为另一个时(通常使用 dev fusion 使用的相同 dll),我总是遇到连接自身的命名空间并将所有内容都搞砸。我之前已经访问过嵌套的私有字段,而无需使用 TypeConverter ......所以我真的很茫然。 @Steiner 你在哪里可以获得用于转换的 dll 开发融合?我在他们的网站上没有看到任何类型的链接,我想尝试编写一个批处理转换器桌面应用程序......如果他们还没有的话。 @Steiner ...关于您的回答,我不认为是这种情况,因为我已经删除了项目的默认(根)命名空间。我之前尝试使用 Import 语句并删除它时已经遇到了这个问题(顺便解决了这个问题),所以我会说不是它。 @ProtoNoob - 好吧,我不完全确定它们是否相同;但是这些 DLL 应该可以帮助您进行自制的持续集成。下载 SharpDevelop 的 MSI 并找到以ICSharpCode.NRefactory
开头的 7-zip DLL(您可以在 7-zip 中打开 msi 并避免安装)。这个页面laputa.sharpdevelop.net/NRefactoryTutorialVideo.aspx 也帮助我做了一些类似于你需要它们的事情。【参考方案2】:
在我看来,不同的编译器在处理嵌套的私有类型时使用了不同的哲学。 C# 说可以从更高级别类型的属性访问它,VB.NET 说不是。也许那些哲学甚至不是故意的。
无论如何,要在 VB.NET 中修复它,您可以使用使用字符串而不是 Type
的 TypeConverterAttribute
构造函数,并将完全限定的嵌套类型名称作为字符串:
<TypeConverter("Aga.Controls.Tree.TreeColumn.TreeColumnConverter"), DesignTimeVisible(False), ToolboxItem(False)> _
Public Class TreeColumn
...
【讨论】:
感谢您的信息,在对 TypeConverter 属性进行了更多研究之后,它看起来像是一个有效的修复,但 Hans Passant 也提出了一个很好的观点。在您看来,哪个更好?我可能会在那个讨论中给出答案。 您将通过设置为Friend
(C# 中的internal
)来更改嵌套类型的可访问性。它可以被同一程序集中的任何其他类型访问。
没错,事实上这是我最初的担忧,但我对在那里使用常量持谨慎态度。有没有理由相信 GetType(TreeColumn.TreeColumnConverter) 会返回除“Aga.Controls.Tree.TreeColumn.TreeColumnConverter”以外的值?我认为不会,但这不是我的代码,我还不太了解所有方法(但我正在努力学习)。
您可以测试生成的代码并检查它是否产生了预期的结果。
嗯,是的,我打算这样做,但是我要转换一个非常大的项目需要一段时间。我只是在技术层面上想知道这两个论点是否有可能达成一致。我唯一能想到的是 GetType 方法是否返回 Nothing/Null 值。以上是关于“私有”可见性修饰符 - 将 C# 转换为 VB 时如何处理差异?的主要内容,如果未能解决你的问题,请参考以下文章