C#“as”运算符和高级转换在循环/函数和 out/ref 参数修饰符和 typeof() [重复]

Posted

技术标签:

【中文标题】C#“as”运算符和高级转换在循环/函数和 out/ref 参数修饰符和 typeof() [重复]【英文标题】:C# "as" operator and advanced conversion use in loops/functions and out/ref parameters modifiers and typeof() [duplicate] 【发布时间】:2013-07-16 17:45:15 【问题描述】:

我需要澄清一下:

是/作为运营商

out/ref 参数修饰符

类型

如果您不喜欢,请随意只回复您知道或想要回复的内容,而不是整个问题。

是的,我要求澄清这些。纠正我或补充我已经说过的内容。

嗯,我用谷歌搜索了一下,然后登陆了各种网站、MSDN 等。我仍然需要有人写一些代码来帮助我阐明整个概念,最后让我充分发挥它的作用,希望这对其他人也有帮助。

基本上我的理解是这样的:

A)

在伪代码中

如果对象是这种类型返回true,否则返回false

简单。还是我在这里做错了什么?

某些类型是否有任何限制或问题?

这段代码运行良好,所以我想我做得很好。

object s = new SqlBoolean();
        if (s is SqlBoolean)
        
            Console.WriteLine("Is SqlBoolean");
            Console.ReadLine();
        

2) 作为

好吧,我还是要完全理解这一点。

MSDN 报告:

as 运算符用于在兼容之间进行转换 类型。 as 运算符类似于强制转换,不同之处在于它在 转换失败而不是引发异常。

好吧,我在一个对象数组上尝试了一个循环,它基本上只转换基元并且有很多问题(每次转换都比一点困难抛出 null 或其他东西)

using System;
using System.Data.SqlTypes;

class ***

    public static void Main()
    
        string country = "jii";
        string vatNum= "dde";

        object[] MyObjects = country,
                              vatNum
                             ;

        for (int i = 0; i<=MyObjects.Length-1;i++)
        
            MyObjects[i] = MyObjects[i] as SqlString?;
            Console.WriteLine(MyObjects[i].ToString() + " " + MyObjects[i].GetType());
            Console.ReadLine();
        
    
 

在我正在制作的程序中,我需要将这些值转换为 SqlStrings、SqlBooleans 等。

请注意我正在使用“SqlString?”行将 SqlString 强制为 Nullable。末尾有问号(?强制为空,谁知道呢!:D)。

所以基本上它对于在不使用异常的情况下进行一些低级转换很有用?还是什么?

3) refout

嗯,基本上 ref 从函数中更改预声明变量的值:

IE

using System;

class ***

    public static void Main()
    
        int x = 10;
        Write(func(ref x).ToString());
        Write(Convert.ToString(x));
    

    public static int func(ref int y)
    
        y += 10;
        return y;
    

    public static void Write(string z)
    

        Console.WriteLine(z);
        Console.ReadLine();

    
 

执行此操作即可,输出为 20 20 删除两个 ref 将输出 20 10

(ref直接改变外部声明的x,而不在方法中创建实例)

出去呢?有什么用???

我听不懂。在某处读取它似乎就像一个与 ref 一样的参数,但它让你以某种方式拥有一些输出参数。

在前面显示的代码中用 out 而不是 ref 只会产生 IntelliSense 的编译错误,我什至不知道如何让这些 out 参数显示。

在我正在做的一个项目中,我正在使用以下代码:

public static Array check(string country, string vatNum)

    bool valid;
    string name;
    string address;
    checkVatService vatchecker = new checkVatService();
    vatchecker.checkVat(ref country, ref vatNum, out valid, out name, out address);

    return new object[] country,
                         vatNum,
                         valid,
                         name,
                         address
                         ;

现在,checkVat 是来自european online checking webservice. 的一些代码

我看到它没有参数,它们是由 webservice 网站 (link to library, if needed) 的 wsdl webservice 消费库生成的

如何使用 out 参数?它们是否可以在不使用 return 的情况下产生一些输出?我如何使用它们?请说的很详细

4) 类型

这会从 System.Type 中返回您传递给它的类型的类型。

首先我想我可以得到我传递给它的任何对象的类型

int x;
SqlBoolean xy = new SqlBoolean();
typeof(x) // integer
typeof(xy) // SqlBoolean

但事实并非如此。

它只是从 System.Type 返回类型。

喜欢

typeof(int).ToString() // System.Int32 或类似的 typeof(xy).ToString() // System.Data.SqlTypes.SqlSqlBoolean

我真的不知道该怎么办。

要获取对象的类型,您必须从对象中执行类似 .GetType 之类的操作。

那么 typeof 的实际用途是什么,我缺少什么?

谢谢大家

【问题讨论】:

阅读有关这些运算符的文档比在 *** 上询问它们更有效率。 代码ˋMyObjects[i] = MyObjects[i] as SqlString?;` 完全没有任何意义。如果对象不是 ˋSqlString ,它将设置值为下一行的访问冲突。如果你尝试过你的代码,你会注意到它不起作用,它应该给你一个提示,你的代码是无效的,你应该阅读官方 MSDN 文档。 【参考方案1】:

大问题..小答案:

    正确。 它允许强制转换无一例外地失败。因此,您可以检查结果是否为null。如果是,则强制转换失败。 ref 通过引用传递对象(注意:仍然是按值传递语义!)。 out 表示必须在函数退出之前分配一个变量。 我不确定我是否理解您对typeof 的问题。如果您不明白它为什么有用(就像任何东西一样,真的),最好忽略它的使用。

【讨论】:

【参考方案2】:

a) 问题你答对了。

b)也许这会带来一些光明 -

http://blogs.msdn.com/b/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

http://msdn.microsoft.com/en-us/library/ms173105.aspx

对于其余部分和上面这个代码项目教程(分为 2 部分)可能会有所帮助:

http://www.codeproject.com/Articles/3114/C-Keywords-Part-I-Modifier-Keywords

http://www.codeproject.com/Articles/3424/C-Keywords-Part-II-Type-Conversion-Operators-and-O

【讨论】:

【参考方案3】:

1) 关于 is 运算符,您是正确的 2) as 运算符的使用是它抑制了错误情况的异常,因此当强制转换错误时,它会抛出 null。 3)参考请参考下面的链接,这里给出了详细的解释Why use the 'ref' keyword when passing an object? 4) out 参数通常用于需要从函数返回多个值的情况。使用return语句直接返回一个值,使用out参数返回其他值。 例如和清楚的理解参考what is use of out parameter in c#。你可以在那里找到 jon skeet 的优秀文章。 5) 可能会出现您想要检查对象的类型以执行某些操作的情况,但根据 RTTI 设计原则,大多数情况下不应该使用这种情况

【讨论】:

【参考方案4】:

typeofGetTypeis都是不同的,可以输出不同的结果。 Refer to this SO post 存在我见过的最简单的解释。


参考和输出

默认情况下,方法的参数是按值传递,这意味着参数的值在传递给方法时会被复制。如果您有foo(int y)y = 9; main()int x = 5; Foo(x);,方法 Foo 将 x 的值复制到 y,然后为 y 分配一个不同的值。 x 仍然保持为 5。如果您有引用类型参数,例如Foo(object y)y = null; main()object x = new object(); Foo(x);,则 y 包含 x 的复制值,这是一个引用值,而不是对象本身。因此,对 y 所做的更改也不会反映在 x 中。相比之下,ref 和 out 是通过引用传递

// Example of ref:
// p DOES NOT copy x's reference value of the object
// p is x (or refer to the same memory as x)

class Ref_Example

   static void Foo(ref int p)  p = 8;
   static void Main()  
      int x = 5; Foo(ref x);
      Console.WriteLine(x);    // output: 8 
   


// Example of out:
// out = ref, except variables need not be assigned before method is called
// You use out when you have to return multiple values from a function  
Class Out_Example

   static void Find_Synonyms(
          string vocab, out string synonymA, out string synonymB)
    // Lookup the synonyms of the word "rich" ;

   static void Main()
   
      string a, b;
      Find_Synonyms("rich", a, b);
      Console.WriteLine(a);   // abundant
      Console.WriteLine(b);   // affluent

当然,您可以打破 ref/out 的设计目的,并通过为变量分配初始值来使用 ref 代替 out,但这没有逻辑意义并且可能会使代码阅读者感到困惑。 (即,您在搜索完同义词之前如何知道它们?为什么要为其分配不正确的初始值?等等)


进一步说明:

int = System.Int32SqlBoolean = System.Data.SqlTypes.SqlBoolean。 int 只是一个别名,可能是由于传统,而 System.Int32 是 C# 类型的完整表示/名称。什么将int x 暴露给x.Equalsx.ToStringx.Parse 之类的方法? System.Int32。在 C# 中,类型是具有定义数据或引用类型的成员的类(例如 System.Int32)。

【讨论】:

【参考方案5】:

这是我自己了解 out and ref 的概念后的真正答案。

Ref -> 当您先前在调用的方法之外初始化变量并且希望该方法为其分配结果值时,您将参数作为 ref 传递。

Out -> 当您调用的方法之外的变量可能已分配或未分配时,您将参数作为输出传递,并且您希望该方法将结果值分配给它

As-> 进行强制转换而不抛出异常。

另外,this

【讨论】:

以上是关于C#“as”运算符和高级转换在循环/函数和 out/ref 参数修饰符和 typeof() [重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥“as”运算符在 C# 中不使用隐式转换运算符?

《C#高级编程》读书笔记:运算符

C#高级编程

浅谈c#的三个高级参数ref out 和Params

浅谈c#的三个高级参数ref out 和Params

C# 篇基础知识2——运算符类型转换流程控制枚举结构体和数组函数