C#是一种安全的语言吗?我的例子怎么样?

时间:2017-04-05 04:21:06

标签: c# typesafe

我在C#中测试以下代码,它可以成功运行。我的问题是我可以在以下示例中将一种类型的数据分配给另一种类型的数据,但为什么它仍然被称为类型安全语言?感谢。

    private XWPFParagraph getParagraph(String string) {
            XWPFParagraph paragraph = new XWPFParagraph(CTP, IBody);
            XWPFRun run = paragraph.createRun();
            run.setText(string);
            return paragraph; 
        }   
    public void generateReport(XWPFDocument document){   
     document.add( getParagraph("aaaaaaaaaaaa"););
   }

可以成功编译,结果为55。

4 个答案:

答案 0 :(得分:4)

类型安全意味着它确保只有类型定义允许的操作才能应用于对象的内存,例如你不能将一个对象强制转换为某种不兼容的类型。

关于连接字符串和整数的+运算符,这在C#4规范的第7.8.4节中指定:

  

对于x + y形式的运算,二元运算符重载   分辨率(第7.3.4节)适用于选择特定的运算符   实现。操作数转换为参数类型   选定的运算符,结果的类型是返回类型   运营商。

     

下面列出了预定义的附加运算符。对于数字和   枚举类型,预定义的加法运算符计算总和   两个操作数。 当一个或两个操作数都是string类型时,   预定义的加法运算符连接字符串表示形式   操作数。

答案 1 :(得分:4)

在评论中回答您重复的问题:

  1. 是C#是一种类型安全的语言?是或否。
    1. 如果答案是肯定的,那么为什么我的代码可以成功编译。这是否意味着我的示例与类型安全问题无关。
    2. 您的示例与类型安全问题无关 首先请注意var只是一个语法糖,编译器会根据右侧为您的变量分配正确的类型。

      换句话说,你问为什么以下是有效的:

      int intNum = 5;
      string strNum = "5";
      string result = intNum + strNum;
      Console.WriteLine(result);
      

      这是有效的,因为.NET支持这种字符串连接,请参阅以下Concat method

      string result = string.Concat(intNum, strNum);
      

      该方法通过调用它们的ToString方法来连接两个参数。

答案 2 :(得分:1)

是的。您的示例使用的是在C#中具有非常不同含义的var,而不是在JavaScript中。在C#中,它更像是一种合成糖。您编写的代码等同于以下内容 -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
           int intNum = 5;
           string strNum = "5";
           string result = String.Concat(intNum, strNum);         
           Console.WriteLine(result);
        }
    }
}

基本上,编译器会查看var声明的右侧以确定正确的类型。这有点告诉编译器获取类型(严格编译时间),因为我懒得去理解它。

但它有更大的用途,它可以让你处理anonymous types

最后,为了毫无疑问地证明var是真正的类型安全,请尝试以下代码段...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var intNum = 5;
           var strNum = "5";
           var result = intNum + strNum;
           // Let's re-purpose result to store an int
           result = 6;
           // or this
           result = intNum;
           Console.WriteLine(result);
        }
    }
}

这在类型不可知的语言中完全有效(再次说是JavaScript)。

答案 3 :(得分:0)

来自 MSDN

  

类型安全代码仅访问其授权的内存位置   访问。 (对于此讨论,类型安全特指   记忆类型安全,不应与a型安全混淆   更广泛的尊重。)例如,类型安全的代码无法从中读取值   另一个对象的私有字段。它只访问类型   明确的,允许的方式。

     

在即时(JIT)编译期间,可选的验证   进程检查元数据和Microsoft中间语言   (MSIL)将JIT编译成本机机器代码的方法   验证它们是否类型安全。如果代码,则跳过此过程   有权绕过验证。有关的更多信息   验证,请参阅托管执行流程。

     

虽然运行托管不是必需的类型安全验证   代码,类型安全在装配隔离和密封中起着至关重要的作用   安全执法。代码是类型安全的,通用语言   运行时可以完全隔离组件。这个   隔离有助于确保组件不会对每个组件产生负面影响   另外,它提高了应用的可靠性。类型安全的组件   即使可信任,也可以在同一进程中安全地执行   不同的水平。当代码不是类型安全时,会产生不必要的副作用   可以发生。例如,运行时无法阻止托管代码   调用本机(非托管)代码并执行恶意代码   操作。当代码是类型安全的时,运行时的安全性强制执行   机制确保它不访问本机代码,除非它具有   允许这样做。所有非类型安全的代码必须是   使用传递的枚举成员授予SecurityPermission   SkipVerification运行。

加上 shorter explanation

  

如果你问的是“类型安全”的概念通常意味着什么,那就是   允许开发人员确定的代码特征   值或对象将表现出某些属性(即,属于   特定类型)以便他/她可以以特定的方式使用它而不用担心   意外或未定义的行为。

......以及关于该网址的深入说明性示例。