C# Static与拓展方法

我们可以使用 static 关键字把类和类成员定义为静态的。
作用

  • 静态成员让类的所有实例化对象之间实现数据共享。
  • 实现成员变量的唯一性,这在单例模式中常用到。
  • 静态类可以作为工具类提供方法

特点

  • 使类成员作为类的成员存在,而不依赖于类的实例化对象。
  • 类,子类,类实例化对象,子类的实例化对象共用一个成员变量。
  • 静态类不可被实例化,不可被继承,只能包含静态成员。
  • 静态构造函数只能用来对类的静态成员变量初始化(不能对静态成员变量初始化),不能被外部调用,并且在类第一次被使用时自动调用。

静态成员变量

class MyClass
{
	public static int age; //访问修饰符 static 数据类型 变量名
}

当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个静态成员。且如果该类被其他类继承,该类和其他子类都共用这个静态成员。静态成员在编译阶段已经存在,且在整个程序周期内一直存在,直到整个程序被关闭。静态成员属于类,类的静态成员变量常用于用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。(当然类的实例化对象也可以获取静态成员)当静态成员变量没有初始化时,系统会生成一个默认静态构造函数为静态成员变量赋值(数值类型是0,引用类型是null)。

static void Main(string[],args)
{
	Console.WriteLine(myClass.age);//直接用 类名.变量名 使用
}

基类子类共用一个静态成员

class BaseClass
{
	public static int age = 10;
}

class MyClass:BaseClass
{
	
}

static void Main(string[],args)
{
	Console.WriteLine(MyClass.age)//输出10
  MyClass.age = 100;
  Console.WriteLine(BaseClass.age)//输出100
}
//MyClass和BaseClass中的age是同一个

静态成员函数

class MyClass
{
	public static int age;
	public static int GetAge() //访问修饰符 static 返回值数据类型 函数名(参数列表)
  {
    return age;
  }
}

和静态成员变量相同,类的静态成员函数也是属于类的,可以直接通过类来调用。此外,静态函数中只能使用静态成员变量(不能使用普通的成员变量)。因为普通的成员变量只有在类实例化对象时才分配内存,当调用静态成员函数时不能去使用没有分配内存的成员变量。静态成员函数中不能使用this关键字。(this代表实例化对象,而静态方法中可以不存在实例化对象)。

静态类

static class MyClass //static class 类名
{
	
}

**静态类不能被实例化,不能被继承,只能包含静态成员。**静态类可以作为提供一些公共静态方法的工具类,例如Console就是一个静态类。

静态构造函数

class MyClass
{
	public static int age;
	static MyClass() //static 类名()
  {
    age = 10;//初始化静态变量
  }
}

静态构造函数用来为类的静态变量初始化,不可被外部调用,没有参数,当类第一次使用时会自动调用。静态类和普通类中都可存在静态构造函数。

拓展方法
为现有的非静态变量类型(自定义的非静态类类,int,string,结构体等)添加新方法。

特点
扩展方法需要写在静态类中,并且是静态方法。

static class Tools
{
	public static void NewFunc(this int value,...)//访问修饰符 static 返回值类型 方法名(this 被添加新方法的变量类型(可以是自定义的类,string,结构体,int等) 被添加新方法的变量类型的对象,参数列表)
  {
    //方法逻辑
  }
}

使用

class MyClass
{
	public string name = "MyClass";

  public void Func1()
  {
    Console.WriteLine("这里是Func1);
  }
}

static class Tools //必须写在静态类中为非静态类型添加方法(MyClass不能是静态类)
{
	//为int类型添加无参数的Speak方法
	public static void Speak(this int value)//没有参数
  {
    Console.WriteLine("我是int类型,我的值为"+value);//这里的value就代表下面的number
  }

  //为int类型添加无参数的Speak方法
  public static void SpeakString(this int value,string str)//有参数
  {
    Console.WriteLine("我是int类型,我的值为"+value+" 传的参数为"+str);//这里的value就代表下面的number
  }

  //为自定义类MyClass添加有参数的Func2方法
   public static void Func2(this MyClass myClass,string str)//有参数
  {
    Console.WriteLine("我是" + str + " 我的类名为"+myClass.name);
  }
}

class Program
{
	static void Main(string[],args)
  {
    int number = 10;
    number.Speak();//输出 我是int类型,我的值为10
    number.SpeakString("值类型");//输出 我是int类型,我的值为10 传的参数为值类型
    MyClass myClass = new MyClass();
    myClass.name = "MyClass";
    myClass.Func2("类");//输出 我是类 我的类名为MyClass
  }
}

在unity中使用

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//工具类
public static class Tools
{
    //为UnityEngine.UI.Image添加 设置图片 方法
    public static void SetIcon(this UnityEngine.UI.Image image,string res)
    {
        image.sprite = Resources.Load<Sprite>($"Icon/{res}");
    }
}


///
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class HeroItem : MonoBehaviour
{
    strint res = "Icon_1"
    void Start()
    {
        transform.Find("Icon").GetComponent<Image>().SetIcon(res);
    }
}

总结

  • 静态成员属于类,而不属于类的对象,使用类或者类对象都可以调用静态成员。
  • 基类和子类共用一个静态成员。
  • 静态成员函数只能使用静态成员变量,不能使用类的非静态成员变量。
  • 静态类不可被实例化,不可被继承,只能包含静态成员。
  • 静态构造函数只能用来对类的静态成员变量初始化(不能对静态成员变量初始化),不能被外部调用,并且在类第一次被使用时自动调用。
  • 拓展方法为现有的非静态变量类型(自定义的非静态类类,int,string,结构体等)添加新方法。
  • 扩展方法需要写在静态类中,并且是静态方法。

你可能感兴趣的:(C#,c#)