using变量不可ref的问题

橘子皮... 2018-11-26 10:56:17

Using rep As HttpWebResponse = xmlhttp.GetResponse()
Using reps As Stream = rep.GetResponseStream()
x = GetRepText(reps)
End Using
End Using

Public Function GetRepText(ByRef reps As Stream, Optional Encode As String = "UTF-8") As String
Using streamreader As StreamReader = New StreamReader(reps, Encoding.GetEncoding(Encode))
Return streamreader.ReadToEnd
End Using
End Function


vb.net里Using里的变量reps可以传址进函数GetRepText(Byref...)

但是在c#里却没法传址进去,提示using里的变量不可ref或者out,这是为什么呢?如何传址进去?


using (HttpWebResponse rep = (HttpWebResponse)xmlhttp.GetResponse())
{
using (Stream reps = rep.GetResponseStream())
{
x = a.GetRepText(ref reps);
}
}

class a{

static public string GetRepText(ref Stream reps, string Encode = "UTF-8")
{
using (StreamReader streamreader = new StreamReader(reps, Encoding.GetEncoding(Encode)))
{
return streamreader.ReadToEnd();
}
}

}

}
...全文
370 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
using 的作用是结构化编成形式、稳定靠谱地调用 IDisposable 的接口方法。那么假设这个结构的核心是 ref 的,这将产生幻象。所以可以说 vb.net 可能是不靠谱的。
  • 打赏
  • 举报
回复
这只能说明 vb.net 这方面有点不靠谱了。
stherix 2018-11-27
  • 打赏
  • 举报
回复
using的变量肯定不能ref 而且c#里,引用类型都是传引用,不是传值,所以并不需要ref修饰,除非你想修改这个变量的引用(问题又回来了,using的变量肯定不能更改引用的)
kevin2y 2018-11-27
  • 打赏
  • 举报
回复
删除了方法定义的ref吧,非值对象默认就是ref。试试
  • 打赏
  • 举报
回复
好奇这段代码里为啥要ref,作用是什么
  • 打赏
  • 举报
回复
上面
    Sub aa(ByRef x As A)
        x = New A
        Debug.Assert(x.TheTimes = 2)
    End Sub
可键 TheTimes 一会儿为2,一会儿(在 using结构中)为1。所以 vb.net 虽然得到了跟 c# 一样的结果(!),但是它的编译器太不靠谱了,对于写 ref 的不给报错提示。
良朋 2018-11-27
  • 打赏
  • 举报
回复
为毛你的回复可以超过三次?
  • 打赏
  • 举报
回复
欸!不对啊!我从新写了一下测试 demo,证明 vb.net 其实在这个 ref 上又搞了一些语法与语义不同的所谓”贴心改动“。
Imports System

Module Program
    Sub Main(args As String())
        Using a = New A
            Debug.Assert(a.TheTimes = 1)
            Debug.Assert(A.Times = 1)
            aa(a)
            Debug.Assert(a.TheTimes = 1)
            Debug.Assert(A.Times = 2)
        End Using
    End Sub

    Sub aa(ByRef x As A)
        x = New A
    End Sub
End Module

Class A
    Implements IDisposable

    Sub New()
        Times += 1
        _Times = Times
    End Sub

    Public Shared Times As Integer
    Private _Times As Integer

    Public ReadOnly Property TheTimes As Integer
        Get
            Return _Times
        End Get
    End Property

    Public Sub Dispose() Implements IDisposable.Dispose
    End Sub
End Class
这里可看到,在 aa 方法中的断言证明 TheTimes 为 2,而在 using 结构中第二个断言证明 TheTimes 仍然为 1。 于是程序员就糊涂了! 说实在的,在使用了 c# 较长一段时间之后,就会觉得 vb.net 在动态特征上搞的这些”贴心的改变“其实是有点过分了。这里又允许 ref,同时又自动修改回 a 变量的引用,那么 vb.net 这种算是什么神操作啊?这个 vb.net 用起来会看来更繁琐了。
  • 打赏
  • 举报
回复
在这个 demo 程序中,原本从基本结构上看,我们是要保证 a 能够靠谱地在离开 using 结构时可靠地调用 Dispose。结果发现调用 aa(a) 之后,其实变量 a 引用的对象已经被偷换了。 那么此时 using 就成了诡异的文章格式了。
  • 打赏
  • 举报
回复
平常我基本上不用 vb.net,为这个帖子我写了一个 vb.net 测试,如下
Imports System

Module Program
    Sub Main(args As String())
        Using a = New A
            Debug.Assert(a.TheTimes = 1)
            aa(a)
            Debug.Assert(a.TheTimes = 1)
        End Using
    End Sub

    Sub aa(ByRef x As A)
        x = New A
    End Sub
End Module

Class A
    Implements IDisposable

    Sub New()
        Times += 1
    End Sub

    Private Shared Times As Integer

    Public ReadOnly Property TheTimes As Integer
        Get
            Return Times
        End Get
    End Property

    Public Sub Dispose() Implements IDisposable.Dispose
    End Sub
End Class
可以看到,第二个断言失败!在编程中,这类 ref 就是一个害人精,而此时助纣为虐的 vb.net 编译器确实是不靠谱的。 我们编程设计中最忌讳地就是扯什么“动态、注入、任意变异类型”的那种害人精的爱好。我们编程要靠谱,所以要求编译器要能在编译器就检查出来尽可能多的设计错误或者说危险的设计模式,决不让那些喜好诡异编码的做法(在运行时、跑几十遍产生特殊数据时才在用户面前丢失人地崩溃,并且难以调试跟踪)轻易混入开发队伍。我们了解哪些才是必要的抽象,哪些是看似高大上实则是要不得的动态特性!
xuzuning 2018-11-27
  • 打赏
  • 举报
回复
using 声明的是封闭的块
在这个块中声明的任何变量在块中均无效,包括 return

1、没有看到你的 ref Stream reps 在块内有任何变化,这也就可能是你认为无效的原因吧
2、块内有 return streamreader.ReadToEnd(); ,但离开块时 streamreader 都不存在了,何来的 ReadToEnd() ?
你需要在块外定义变量,承接 streamreader.ReadToEnd() 的返回
var res = "";
using (StreamReader streamreader = new StreamReader(reps, Encoding.GetEncoding(Encode)))
{
res = streamreader.ReadToEnd();
}
return res;
3、既然方法体内并无改变 reps 的代码,又何苦 ref 呢?况且 Stream 是引用类型,并无 ref 的必要

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧