【从Java到C#系列 二】从java到.net 基础

文章主要目标是让一个java程序员如何迅速适应.net的开发环境,在上一篇已经讲到了开发环境的安装,接下来计划使用两篇博客迅速上手C#,这是第一篇,主要从基础语法和一些简单操作里来体现,通过对比学习的方法,更加深刻的掌握.net的用法和规则,因为楼主即将转向.net开发,所以这里在对比阐述的时候会对c#重点分析。
学习内容来源于:

菜鸟教程http://www.runoob.com/csharp/csharp-methods.html

#C#与Java不同的地方

##整体结构
整体结构的不通风主要体现在层次架构上,java的结构是 项目–包--类(成员变量+成员方法)。而C#则是使用 解决方案–命名空间–类(成员变量+成员函数),接下来从以下几个方面,对整体上的一些不同进行详述。
###程序结构
这里写图片描述

  • 程序的第一行 using System; - using 关键字用于在程序中包含 System 命名空间。 一个程序一般有多个 using 语句。相当于java里的import,引入你需要的包
  • 下一行是 namespace 声明。一个 namespace 是一系列的类。HelloWorldApplication 命名空间包含了类 HelloWorld。相当于java里的包,该包下可以有很多类
  • 下一行是 class 声明。类 HelloWorld 包含了程序使用的数据和方法声明。类一般包含多个方法。方法定义了类的行为。在这里,HelloWorld 类只有一个 Main 方法。相当于java里的类
  • 下一行定义了 Main 方法,是所有 C# 程序的 入口点。Main 方法说明当执行时 类将做什么动作。

###基本语法
语法上的不同,体现在标识符上,而这时唯一的区别就是,java使用的特殊字符是$符,而C#使用的是@符。
###输入输出

  • 输出语句 Console.WriteLine("Hello World"); 用于向控制台输出语句,类似于java里的System.out.println()。
    在输出上java显然更好用一些,直接字符串和参数拼接,而C#需要使用占位符
static void Main(string[] args)
{
    Console.WriteLine("A:{0},a:{1}",65,97);
    Console.ReadLine();
}

输出顺序与占位符顺序一一对应。

  • 输入语句 Console.ReadLine("Hello World");用于读入用户输入的数值,类似于java里的Scanner,不过比Scanner方便了很多

  • Console.ReadKey(); 是针对 VS.NET 用户的。这使得程序会等待一个按键的动作,防止程序从 Visual Studio .NET 启动时屏幕会快速运行并关闭。

###继承和实现的书写

  1. java里的继承使用extends关键字,实现使用:关键字,而C#统一使用:,在书写规范上C#推荐接口用I开头来区别类和接口的不同。
  2. java里子类调用父类方法或者实现父类构造方法使用super关键字,而在C#里使用base关键字

##成员变量
成员变量的不同体现在一些常量,不同的变量,C#定义较为繁琐
###常量
C#里的常量使用专用关键字const,而java则使用final。之后还会提到C#定义不可继承方法的时候有专用关键字sealed,而java依旧使用final。
###数据类型
这里写图片描述
####对于值类型
C#的数据类型里多了很多无符号的值类型,而且多了一个精度更高的 decimal类型。
####对于引用类型
对象类型,字符串类型不用多数,主要的不同就是动态类型,相对于java里的“假”的泛型,我感觉C#的泛型可以说是真泛型了
####对于指针类型
C#官方都说了是不安全方式,我感觉有指针的存在只是为了照顾之前的C和C++的学习者吧。
###类型转换
类型转换上,C#似乎更方便,提供了很全面的方法,显式转换与隐式转换与java大同小异。
###可空类型
该类型在java里并不存在,也不知道这种类型存在的意义
####定义
C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值

using System;
namespace CalculatorApplication
{
   class NullablesAtShow
   {
      static void Main(string[] args)
      {
         int? num1 = null;
         int? num2 = 45;
         double? num3 = new double?();
         double? num4 = 3.14157;
         
         bool? boolval = new bool?();

         // 显示值
         
         Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}", 
                            num1, num2, num3, num4);
         Console.WriteLine("一个可空的布尔值: {0}", boolval);
         Console.ReadLine();

      }
   }
}

运行结果

显示可空类型的值: , 45,  , 3.14157
一个可空的布尔值:

####合并运算符
Null 合并运算符用于定义可空类型和引用类型的默认值。Null 合并运算符为类型转换定义了一个预设值,以防可空类型的值为 Null。Null 合并运算符把操作数类型隐式转换为另一个可空(或不可空)的值类型的操作数的类型。
如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。下面的实例演示了这点:

using System;
namespace CalculatorApplication
{
   class NullablesAtShow
   {
         
      static void Main(string[] args)
      {
         
         double? num1 = null;
         double? num2 = 3.14157;
         double num3;
         num3 = num1 ?? 5.34;      
         Console.WriteLine("num3 的值: {0}", num3);
         num3 = num2 ?? 5.34;
         Console.WriteLine("num3 的值: {0}", num3);
         Console.ReadLine();

      }
   }
}

运行结果

num3 的值: 5.34
num3 的值: 3.14157

##成员方法
###访问修饰符
C#提供了5种级别的访问修饰符限定

Private:对象本身在对象内部可以访问;和java一样
Internal:同一个程序集的对象可以访问(对应于java里的default);

Protected:只有该类对象及其子类对象可以访问同一个包中不能访问,这个算是C#比较特有的。

Protected internal:该程序集内的派生类访问,是protected和internal的交集(Protected Internal 访问修饰符允许在本类,派生类或者包含该类的程序集中访问。这也被用于实现继承。);和java里的protected一样

Public:所有对象都可以访问;和java一样

###方法的参数传递
这里写图片描述
前两种与java的相同,主要区别在于C#多了一种叫做“输出参数”的传递形式。看了很多,理解到,输出参数最重要的作用就是:当需要从一个参数没有指定初始值的方法中返回值时,输出参数特别有用

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValues(out int x, out int y )
      {
          Console.WriteLine("请输入第一个值: ");
          x = Convert.ToInt32(Console.ReadLine());
          Console.WriteLine("请输入第二个值: ");
          y = Convert.ToInt32(Console.ReadLine());
      }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部变量定义 */
         int a , b;
         
         /* 调用函数来获取值 */
         n.getValues(out a, out b);

         Console.WriteLine("在方法调用之后,a 的值: {0}", a);
         Console.WriteLine("在方法调用之后,b 的值: {0}", b);
         Console.ReadLine();
      }
   }
}

要知道,这里a,b都没有赋初值,但是依然可以使用,这就是输出参数的好处所在。

请输入第一个值:
7
请输入第二个值:
8
在方法调用之后,a 的值: 7
在方法调用之后,b 的值: 8

###重写
几个区别比较大的地方
1,C#里是通过抽象类:虚方法virtual和abstract实现动态多态
####抽象方法
和虚方法类似,只不过没有方法体,和java的类似。
####虚方法
和java里的普通方法类似,但感觉更加规范了,只有需要重写的时候才尽量用virtual方法,其它时候用普通方法。java这块儿就比较模糊了(只要方法名相同,就默认重写)。Java默认的多态,C#要求加上virtual(被继承的方法)和override(继承的方法),而且C#要求不能改变原来的访问修饰符,不像java那样,可以指定更加宽松的访问方式。如果有人利用C#来写程序,必须经常带上virtual和override,还必须照抄原来的访问控制符

using System;

class A
{

    public void F()
    {

        Console.WriteLine("A.F");
    

    }

    public virtual void G()
    {

        Console.WriteLine("A.G");
        Console.ReadKey();

    }

}

class B : A
{

    new public void F()
    {

        Console.WriteLine("B.F");
       

    }

    public override void G()
    {

        Console.WriteLine("B.G");
        Console.ReadKey();

    }

}

class Test
{

    static void Main()
    {

        
        A a= new B();
        a.F();
        a.G();

    }
}

输出结构

A.F  //编译看左边,运行看右边,编译看非虚,运行看虚方法
B.G

感觉virtual这个关键字有点儿鸡肋,觉的还是java的方便理解一些

####sealed方法
其实和java里的final差不多,修饰的类不可继承
##一些结论
1,C#和java最大的区别就是java各方面规定比较宽泛,而C#则粒度更加细致,每个方面都规定的特别多详细
2,如果说写代码的体验,肯定是java更好一点儿,不是那么细分,比较好理解,但有些东西规范的比较宽泛,出了错不好排错。如果搭配ide来食用的话,感觉C#+2015食用起来更佳,很多便于团队协作和注释之类的设置,而且2015功能非常强大,但鸡肋的地方就是每次调试都要出框,关了才能修改,比较麻烦,当然也有可能是我现在还没有熟练使用的原因。

#C#额外可使用的地方

##结构体

  1. 结构可带有方法、字段、索引、属性、运算符方法和事件。
  2. 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
  3. 与类不同,结构不能继承其他的结构或类。结构不能作为其他结构或类的基础结构。结构可实现一个或多个接口。
  4. 结构成员不能指定为 abstract、virtual 或 protected。
  5. 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
    如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。

不知道该怎么形容结构体,感觉就是为了适用之前的C强行加的。

##析构函数
可能是因为没有JVM如此强大的垃圾回收能力吧,所以使用析构函数来弥补CLR的不足吧,但好像官方也不怎么推荐这个功能。
##预编译与条件指令
1,预处理器指令指导编译器在实际编译开始之前对信息进行预处理。
所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
2,C# 编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。在 C# 中,预处理器指令用于在条件编译中起作用。与 C 和 C++ 不同的是,它们不是用来创建宏。一个预处理器指令必须是该行上的唯一指令。

未完待续,现在只是粗浅的认识,之后随着学习的深入会一直更新。。。

发布了243 篇原创文章 · 获赞 119 · 访问量 18万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 点我我会动 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览