C#语言学习之旅(2):C#对象和类型

在本章节内容,主要关于类的细节处理和结构体一点点介绍。

2.1 类和结构

类和结构体实际上都是创建对象的模板,每个对象都有包含数据,并提供了处理和访问的方法。类和结构体得区别是他们在内存的存储方式上的引用,类是存储在堆上的引用类型,而机构体是存储在堆栈上的值类型。在较小的数据类型使用结构可以提高性能,但在语法上和类很相似。主要区别在于是使用关键字struct代替class来声明结构体。

 代码如下:

结构体
   struct PhoneStruct //结构体
    {
        
string firstName;
        
string lastName;

    }

 2.2 ref参数

ref参数,是指类中一般方法的ref参数。如果一个方法的参数前带有ref关键字,则该方法对变量所作的任何改变 都会影响到原来对象的值。

Ref参数示例
using System;
using System.Collections.Generic;

namespace CSharpDemo
{
    
class Program
    {
        
static void Main(string[] args)
        {
            Console.WriteLine(TimeOfDay.Moring);
            
int i = 20;
            doSomeThing(
ref i);
            Console.WriteLine(i.ToString());
        }

        
public enum TimeOfDay
        {
            Moring
=0,
            AfterNoon
=1,
            Evening
=2
        }
        
static void doSomeThing(ref int i)
        {
            i 
= i + 100;
           
        }


    }

}

 注意事项:在传递给方法前,无论是值传递,还是引用传递,变量都需要初始化。

 2.3 out 关键字

在方法的输入参数前面加了out关键字时,传递给对方的变量可以不初始化。

out关键字
using System;
using System.Collections.Generic;

namespace CSharpDemo
{
    
class Program
    {
        
static void Main(string[] args)
        {
            Console.WriteLine(TimeOfDay.Moring);
            
int i;
            doSomeThing(
out i);
            Console.WriteLine(i.ToString());
        }

        
public enum TimeOfDay
        {
            Moring
=0,
            AfterNoon
=1,
            Evening
=2
        }
        
static void doSomeThing(out int i)
        {
            i 
=  100;
           
        }


    }

}

 out和ref区别:

ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。

使用ref前必须对变量赋值,out不用。

out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。

2.4 方法重载

方法重载只需声明同名但参数个数或者类型不同的方法即可

方法重载
     //方法重载
        public void doSomeThing(int i)
        {
            i 
= 100;

        }
        
//方法重载
        public void doSomeThing(string i)
        {
            i 
= "111";
        }

 注意事项:

1.C#重载不支持可选参数

2.重载不能仅在返回类型上有所区别

3.重载不能仅根据参数声明为ref还是out区别

2.5 只读字段readonly

readyonly关键字比const灵活的多,允许把一个字段设置为常量,但可以执行一些运算,来确定其初始值,其规则是可以在构造函数中给只读字段赋值,但不能在其他地方赋值。若要设置只读字段为静态,那么必须设置显式声明。

 2.6 部分类 partial关键字

partial关键字允许把类、结构体或接口放在多个文件中。一般类存储在一个文件中。但有时候多个开发人员需要访问同一个类,或者某种类型的代码生成器生成了一个类某部分,所以把类放在多个文件时有益的。

partial
     //demo.cs
        partial class demo1
        {
            
public void method1()
            {

            }
        }
        
//demo1.cs
        partial class demo1
        {
            
public void method2()
            {

            }
        }

 2.7 静态类

静态类使用可以不创建实例化,就可以调静态类中的方法。如下示例:

静态类
using System;
using System.Collections.Generic;

namespace CSharpDemo
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//Console.WriteLine(TimeOfDay.Moring);
            
//int i;
            
//doSomeThing(out i);
            
//Console.WriteLine(i.ToString());
            StaticClass.helpMe();
        }

    }
    
public static class StaticClass
    {
        
public static void helpMe()
        {
            Console.WriteLine(
"help");
        }
    }

}

 2.8 扩展方法

有许多方法扩展类。如果有类的源代码,继承就是给对象添加功能的好方法,但是若果没有源代码怎么办呢,这个时候我们就可以使用扩展方法啦。它允许改变一个类,但不需要改变源代码。扩展方法是静态方法,是类的一部分,但实际上没有放在类得源代码中。

 假如一个money类需要一个方法AddToAmount(decimal amountToAdd)。但是我不修改源代码,此时创建一个静态类,把方法AddToAmount添加为一个静态方法,代码如下:

Money类
using System;

namespace Wrox.ProCSharp.OOCSharp
{
   
class MainEntryPoint
   {
      
static void Main(string[] args)
      {
         Money cash1 
= new Money();
         cash1.Amount 
= 40M;
         Console.WriteLine(
"cash1.ToString() returns: " + cash1.ToString());
         
//Extension Method
         cash1.AddToAmount(10M);
         Console.WriteLine(
"cash1.ToString() returns: " + cash1.ToString());
         Console.ReadLine();
      }
   }
   
class Money
   {
      
private decimal amount;

      
public decimal Amount
      {
         
get
         {
            
return amount;
         }
         
set
         {
            amount 
= value;
         }
      }
      
public override string ToString()
      {
         
return "$" + Amount.ToString();
      }
   }

}


money扩展方法
namespace Chapter3.Extensions
{
  
public static class MoneyExtension
  {
    
public static void AddToAmount(this Money money, decimal amountToAdd)
    {
      money.Amount 
+= amountToAdd;
    }
  }
}

 说明:调用扩展方法使用.cash1.AddToAmount(18M);

原文地址:https://www.cnblogs.com/ylwn817/p/2051547.html