我在c#中有一个项目正在使用另一个用vb.net编写的项目.我目前能够修改它们.
我在VB项目中有一个方法,如:
Public Sub MethodName(ByVal param1 As String, ByRef param2 As String)
param2 = param1 + 1
End Sub
Run Code Online (Sandbox Code Playgroud)
我无法使用C#中的out关键字调用此方法:
public void CallOtherMethod()
{
string param1 ="test";
string param2;
provider.AddTransaction(param1, out param2);
}
Run Code Online (Sandbox Code Playgroud)
VB.Net中的ByRef关键字不应该具有"ref"和"out"的能力吗?
我应该选择参考吗?
有没有办法知道是否已经设置了out参数.这是我正在寻找的伪代码:
public virtual string blabla(long num, out bool bval)
{
if (!bval.HasValue)
{
//Do some default logic
bval = defaultValue;
}
return blabla2(num, bval);
}
Run Code Online (Sandbox Code Playgroud) Visual Studio中的代码度量分析器以及代码度量电源工具,TestMethod将以下代码方法中的代码行数报告为8.
最多,我希望它报告代码行为3.
[TestClass]
public class UnitTest1
{
private void Test(out string str)
{
str = null;
}
[TestMethod]
public void TestMethod()
{
var mock = new Mock<UnitTest1>();
string str;
mock.Verify(m => m.Test(out str));
}
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么会这样吗?
更多信息
经过一番挖掘后,我发现out从Test方法中删除参数并更新测试代码会导致LOC被报告为2,我认为这是正确的.添加out会导致跳转,因此不是因为大括号或属性.
用dotPeek反编译DLL会显示相当多的额外代码,因为out参数可以被认为是8 LOC,但删除参数和反编译也会显示生成的代码,可以认为是5 LOC,所以它不仅仅是VS的问题计算编译器生成的代码(我不相信它应该做什么).
通过在C#7.0中引入ValueTuples,我们现在可以拥有多个返回值:
public (int sum, int count) GetTallies()
{
return (1, 2);
}
Run Code Online (Sandbox Code Playgroud)
我的印象是,out参数的唯一原因是提供一种限制只有一个返回值的解决方法。但是,out参数也得到了改进,这告诉我C#设计人员认为它们不会过时。
我是否缺少某些东西,或者是out var declaration为了简化旧库的使用而引入公正的原因?
为了进一步阐明这个问题:我可以做什么out,我不能做ValueTuples什么?
在jquery中执行clickout的最简单方法是什么?如果在其外部的任何位置单击div框,则隐藏div框.
有没有办法改变flash播放器的音频输出设备?如果没有,是否有一个瑞士法郎玩家有这种可能性?谢谢!
好吧,我对ParameterInfo班级的属性感到困惑.
不幸的是,文档不是很清楚:示例显示了如何构建方法,但没有显示这些方法在C#中的外观.
Cane有人告诉更多关于这些属性:
DefaultValueHasDefaultValueIsInIsLcidIsOptionalIsOutIsRetval哪种组合导致什么方法参考.
我做了一个简单的程序,它给出了以下输出:
方法名称M1 void M1(object param)
IL签名:.method public hidebysig instance void M1(object param) cil managed
方法参数说明:
通过引用传递False
HasDefaultValue = False
IsIn = False
IsLcid = False
IsOptional = False
IsOut = False
IsRetVal = False
方法名称M2 void M2(object param = null)
IL签名.method public hidebysig instance void M2([opt] object param) cil managed
方法参数说明:
通过引用传递False
HasDefaultValue = True
DefaultValue = null
IsIn = False
IsLcid = False
IsOptional …
使用此构造:
var dict = new Dictionary<int, string>();
var result = (dict?.TryGetValue(1, out var value) ?? false) ? value : "Default";
Run Code Online (Sandbox Code Playgroud)
我收到一个错误消息,说CS0165 use of unassigned local variable 'value'那不是我期望的。怎么value可能不确定?如果字典为null,则将返回内部语句false,这将使外部语句的值为false,返回Default。
我在这里想念什么?只是编译器无法完全评估该语句吗?还是我搞砸了?
鉴于此代码:
private void TryIt(Dictionary<int, int> myDict)
{
if (myDict?.TryGetValue(1, out int myValue) ?? false)
{
Console.Out.WriteLine(myValue); // <-- Error CS0165
}
}
Run Code Online (Sandbox Code Playgroud)
C# 编译器发出:
error CS0165: Use of unassigned local variable 'myValue'
Run Code Online (Sandbox Code Playgroud)
但当操作员跳过调用myValue时,显然无法引用。这是因为结果被转换为by 。TryGetValue()?.nullfalse?? false
换句话说,如果myDictis null,?.操作员将跳过对 的调用TryGetValue(),保持myValue未分配状态。我明白了。
但是??操作符将始终评估到 的 null 传播false,从而防止在这种情况下进入 if 块。
这在编译时很明显,那么为什么会出现错误呢?
我怀疑这可能与所有这些语法糖最终如何分解为实际的 .NET p 代码有关,但错误似乎仍然是错误的......
不使用.?运算符时,我不会收到任何错误,这是预期的:
if (myDict.TryGetValue(1, out int myValue))
{
Console.Out.WriteLine(myValue); // …Run Code Online (Sandbox Code Playgroud) 我刚刚了解到将泛型参数作为out参数类型会强制该泛型类型保持不变。这让我很惊讶。我认为out参数被视为与返回类型相同(即如果泛型参数是协变的,那么它可以用作out输出参数),因为它们都是方法的“输出”。
经过一番调查,我意识到你不能这样做:
public class Program {
public static void Main() {
// cannot convert from 'out object' to 'out string'
F(out object s); // passing an out object
}
public static void F(out string o) {
o = null;
}
}
Run Code Online (Sandbox Code Playgroud)
这解释了为什么out参数必须是不变的。但是,我仍然不明白为什么你不能这样做。众所周知,out参数只是返回值的另一种方式。F可以用返回值重写,它会起作用:
// This is the semantically equivalent version of the above, just without "out"
public class Program {
public static void Main() {
object s = F(); …Run Code Online (Sandbox Code Playgroud) out ×10
c# ×7
audio ×1
c#-7.0 ×1
click ×1
code-metrics ×1
flash ×1
hardware ×1
jquery ×1
nullable ×1
parameters ×1
ref ×1
reflection ×1
tuples ×1
vb.net ×1