使用 HttpWebRequest.Create 时的 C# vs VB 语法
Posted
技术标签:
【中文标题】使用 HttpWebRequest.Create 时的 C# vs VB 语法【英文标题】:C# vs VB syntax when using HttpWebRequest.Create 【发布时间】:2015-05-26 22:06:23 【问题描述】:我在 VB 中编码已经有一段时间了,我也可以在 C# 和 F# 中做很多事情,但是 VB 和 C# 之间的一个语法差异仍然让我感到厌烦。我会用谷歌搜索这个,但我不知道该怎么称呼它。考虑以下示例:
在 Visual Basic 中我会这样做:
Dim Request As HttpWebRequest = HttpWebRequest.Create("www.google.com")
但是,当我对 C# 进行看似“逻辑”的转换时:
HttpWebRequest Request = HttpWebRequest.Create("www.google.com");
我得到隐式类型转换错误。在查看了其他一些代码后,我意识到这似乎是正确的方法:
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create("www.google.com");
但我并不清楚括号中额外提及 HttpWebRequest 类型的目的是什么。这是我不知道的某种类型的转换语法吗?这里发生了什么使这项工作有效,而直接转换无效?
【问题讨论】:
避免这种情况的一种简单方法是改用var
。即var Request = HttpWebRequest.Create("www.google.com");
不能使用 var - 我需要 HttpWebRequest 对象来设置一些属性 - 我不能设置 .Accept 与使用 var 时返回的 WebRequest 对象。不过信息很好。
VB.net 为您进行转换,从某种意义上说,您从两种方法中都获得了 WebRequest,只是 C# 不会为您进行转换,这是您的责任。大多数情况下我宁愿使用HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.google.com")
相关:C# HttpWebRequest vs WebRequest(即它不是真的 HttpWebRequest
)。
【参考方案1】:
HttpWebRequest.Create
返回一个WebRequest
。
HttpWebRequest.Create
确实返回了一个派生自WebRequest
的HttpWebRequest
,但编译器不知道它实际上是一个HttpWebRequest
,但它确实知道您正在尝试将它放入一个变量中HttpWebRequest
类型。
这就是为什么你必须明确输入它。
【讨论】:
【参考方案2】:对于初学者,是的,该语法是 explicit-cast(有时称为 C 样式转换)。
您在这里需要它的原因很简单。 Create
方法实际上继承自WebRequest
类,它返回一个WebRequest
(不是HttpWebRequest
)对象。注意它在HttpWebRequest
和Create
的签名中不存在
分配给 HttpWebRequest
变量然后需要向下转换,这永远不能保证是安全的,因此您必须显式转换它。
请注意,以下代码也可以编译。
WebRequest Request = HttpWebRequest.Create("www.google.com");
【讨论】:
谢谢,我认为这可以解决问题,而且我确实注意到您提供的示例也很好。我的问题是我需要为 Request 对象设置一堆属性。 Accept、Host 等,但似乎并非所有这些都可用于 WebRequest 对象。关于更好的方法在这里做的任何建议?顺便说一句,在 C# 讨论的上下文中可能会被禁止,但我非常想念我们在 VB 中使用“With”。 @MattB 不熟悉该语法,抱歉 :( 无论如何,有时需要向下转换。我会进行as
检查或类似检查以避免出现异常由于某种原因,您没有得到HttpWebRequest
对象,但仅此而已。有关 as 与 cast 的更多信息,请参阅:***.com/questions/496096/…
我一定会仔细阅读的。基本上With
允许您通过指定您的对象一次来设置后续行的属性,而无需一遍又一遍地重新输入对象名称。在 VB 中,我将使用With Request
,然后通过仅键入.Method = "POST"
而不是键入完整的Request.Method = "POST"
在下一行的选项卡式块中设置类似方法。这没什么大不了的,但据我所知,C# 没有等价物。 using
差不多,但还是有很大不同。
@MattB 你可以用初始化器做类似的事情,但在这种情况下,是的,我知道 C# 没有等效的东西。
是的,我在初始化程序的上下文中看到了它,但在这种情况下似乎不是一个选项。【参考方案3】:
正如其他人所说,HttpWebRequest.Create
方法不会返回转换为HttpWebRequest
类型的对象。相反,它返回一个HttpWebRequest
对象作为其基本WebRequest
类型。正如您所发现的,在 C# 中,您需要将对象显式转换为所需的类型。
但是,您的困惑是您假设您不需要在 VB.NET 中执行强制转换操作。您不需要在 VB.NET 中强制转换的唯一原因是因为您拥有Option Strict Off
。如果您在 VB.NET 中转换了Option Strict On
,正如您很可能应该的那样,那么您将需要执行转换,就像在 C# 中一样:
Dim Request As HttpWebRequest = DirectCast(HttpWebRequest.Create("www.google.com"), HttpWebRequest)
这是当您拥有 Option Strict On
时 Visual Studio 显示的编译器错误:
Option Strict On 不允许从“System.Net.WebRequest”到“System.Net.HttpWebRequest”的隐式转换。
当您拥有Option Strict Off
时,VB.NET 将为您执行扩展转换,而不会发出任何警告。这可能很方便,但它会关闭一些编译器类型检查,这可能会为您捕获一些错误。我的经验法则是始终打开Option Strict On
,除非在您需要它的地方Off
。
换句话说,通过转Option Strict On
,正如大多数人所推荐的那样,VB.NET 的类型检查与 C# 的工作方式相同。如果您不想在 C# 中强制转换对象,您可以使用 var
或 dynamic
关键字来完成类似的事情,但在大多数情况下我不会推荐它。类型检查是你的朋友。 C# 中类型转换的语法更简单这一事实使它更加方便。
【讨论】:
我以前一直打开 Option Strict。特别是在我学习的时候,我仍然向其他正在学习的人推荐它。话虽如此,但使用所有 DirectCast 和 TryCasts 等,它使某些代码块更难阅读,所以我逐渐远离它。我们编写的代码通常分发给非常狭窄的受众,我们知道每台 PC 几乎完全相同,而且它的范围通常相当狭窄并且经过大量测试,因此我们不再担心 Option Strict 是否启用。但它确实有它的位置,非常适合学习。 在某些情况下,转向Option Strict Off
很有价值,例如在后期绑定到动态加载的库时避免大量反射代码。我同意CType
和DirectCast
是一种不优雅的语法,但我不认为仅仅为了避免偶尔使用强制转换运算符而转向Option Strict Off
是一个很好的原则。如果您发现 VB.NET 的语法过于冗长,这是考虑切换到不那么冗长的语言的好理由,但不是为了省点打字而关闭其功能的好理由。【参考方案4】:
这是由于在您的 VB 项目中将Option Strict
设置为off
。如果你把它 on
隐式缩小转换将产生编译错误,就像它在 C# 中一样。你必须在 VB 中编写以下代码:
Dim Request As HttpWebRequest = DirectCast(HttpWebRequest.Create("www.google.com"), HttpWebRequest)
相当于C#的
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create("www.google.com");
【讨论】:
我已经接受了另一个答案,并获得了大量有用的信息,但是来自 VB 背景,这是简短、甜蜜、完全直接的答案,简洁地触及了所有要点.做得好,你得到了我的支持!【参考方案5】:你可以使用:
var Request = HttpWebRequest.Create("www.google.com") as HttpWebRequest;
【讨论】:
确保在之后检查Request
是否为空 :)
是的,当演员表无效时它将为空。使用 as
运算符时检查 null。但是,在这种特定情况下,除非create
返回一个空对象,否则它永远不会为空。
@BradleyDotNET 谢谢!以上是关于使用 HttpWebRequest.Create 时的 C# vs VB 语法的主要内容,如果未能解决你的问题,请参考以下文章
C#使用HttpWebRequest请求url出现远程服务器返回一个错误:401未经授权
用C#代码 get请求获取网页响应代码,通过HttpWebRequest的GetResponse()方法报异常,我想获取这相应代码