using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Wrox3
{
class Fex1
{
//构造函数
//声明基本的构造函数就是声明一个与包含的类同名的方法,但该方法没有返回类型
public class myClass
{
public myClass() { }
public myClass(int number)
{
//
}
}//没有必要给类提供构造函数,编译器会在后台生成一个默认的基本的构造函数,只能把所有的成员字段初始化默认值
//重载与其他方法相同,可以为构造函数提供任意多的重载,只要签名有明显的区别即可
//如果提供了带参数的构造函数,编译器就不会自动提供默认的构造函数
public class myNumber
{
private int _number;
public myNumber(int number)
{
_number = number;
}
}//如果把构造函数定义为private/protected,那么不想关的类就不能访问它
//如果没有任何公有或受保护的构造函数,就不能被new实例化,但是可以在内部编写一个公有的静态属性或方法,进行实例化操作
//类仅用作某些静态成员或属性的容器,不能实例化,可以用static声明此类,让类只能包含静态成员
//类仅通过调用某个静态成员函数来实例化--对象实例化的类工厂方法
//单例模式
public class Singleton
{
private static Singleton s_instance;
private int _state;
private Singleton(int state)
{
_state = state;
}
public static Singleton Instance
{
get => s_instance ?? (s_instance = new Singleton(42));
//Singleton类包含一个私有构造函数,只能在类中实例化它本身
//如果这个字段尚未初始化null,就会调用实例构造函数创建一个新的实例
//检查null,使用合并运算符。如果是null,就会处理操作符右边,调用实例构造函数
}
//若构造哈数的实现由一个表达式组成,那么可通过一个表达式来实现
public class Singletons
{
private static Singletons s_instance;
private int _state;
private Singletons(int state) => _state = state;
public static Singletons instance => s_instance ?? (s_instance=new Singletons(42));
}
}
//如果在一个类中有几个构造函数,以容纳可选参数,这些构造函数包含一些共同代码
class Car
{
private string _description;
private uint _nWheels;
public Car(string description, uint nWheels)
{
_description = description;
_nWheels = nWheels;
}
public Car(string description)
{
_description = description;
_nWheels = 0;
}
}
//两个构造函数初始化相同的字段,可以利用构造函数初始化器
class Car1
{
private string _description;
private uint _nWheels;
public Car1(string description,uint nWheels)
{
_description=description;
_nWheels = nWheels;
}
public Car1(string description):this (description,4) {}
//this关键字仅调用参数最匹配的那个构造函数,需要注意初始化器要在构造函数的代码块之前执行
}
//静态构造函数
//C#可以给类编写无参数的静态构造函数,只执行依次,前面的构造函数时实例构造函数,只要创建类的对象,就会执行它
class Myclass
{
static Myclass()
{
//
}
//类有一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性
//无参数的实例构造函数可以与静态构造函数在同一个类中定义
}
public static class UserPreferences
{
public static Color BackColor { get; }
static UserPreferences()
{
DateTime now = DateTime.Now;
if(now.DayOfWeek == DayOfWeek.Saturday || now.DayOfWeek == DayOfWeek.Sunday)
{
BackColor = Color.Red;
}else
{
BackColor = Color.Green;
}
}
}
}
class Fex2
{
//结构
/*public class Dimensions
{
public Dimensions(double length, double width)
{
Length = length;
Width = width;
}
public double Length { get; }
public double Width { get; }
}*/
//用关键字struct代替class,定义一个结构而不是类
public struct Dimensions
{
public Dimensions(double length, double width)
{
Length = length;
Width = width;
}
public double Length { get; }
public double Width { get; }
public double Diagonal => Math.Sqrt(Length * Length + Width * Width);
// var point = new Dimensions();
// point.Length = 3;
}//结构是值类型,存储在栈中,与简单数据类型一样 但常常当作类来处理
//结构不支持继承
//与构造函数区别,编译器会自动提供一个默认值
//使用结构可以指定字段如何在内存中布局
//只读结构 radonly 不变性
//从属性中返回一个值类型时,调用方会收到一个副本,设置属性只更改副本
public readonly struct Dimensions1
{
public double Length { get; }
public double Width { get; }
public Dimensions1(double length, double width)
{
Length = length;
Width = width;
}
public double Diagonal => Math.Sqrt(Length * Length + Width * Width);
}
//继承
//结构不能从一个结构中继承,唯一例外是对应的结构最终派生了System.Object
//如果要重写ToString()方法
//结构继承链是:每个结构派生自System.ValueType类,这个类又是派生自System.object,ValueType并没有给Object添加新成员但提供了一些结构的实现方式
//结构的构造函数
public class Dimensions2
{
public Dimensions2(double length, double width)
{
Length = length;
Width = width;
}
public double Length { get; }
public double Width { get; }
}
//ref结构
//结构也可以放置在堆上,为对象分配一个结构体,会在堆中创建一个对象
ref struct ValueTypeOnly
{
//
}
}
class Fex3
{
//按值和按引用传递参数
//changa方法接受类型A的参数,把X的值改为2
public static void ChangeA(A a)
{
a.X = 2;
}
//Main方法创建类型A的实例,把x初始化为1,调用changeA方法
static void Main()
{
A a1 = new A { X = 1 };
ChangeA(a1);
Console.WriteLine($"a1.X:{a1.X}");
}
//假设A是结构
public struct A1
{
public int X { get; set; }
}
//结构按值传递,通过值传递changeA方法中的变量a得到堆栈中变量a1的一个副本。
//在方法ChangeA的最后修改并销毁副本,a1的内容从不改变,一直是1
//当A作为类时,完全不一样了
public class A
{
public int X { get; set; }
}
//避免混淆,最好把结构设置为不可变得
//类按引用传递,其中a变量把堆上的同一个对象引用为变量a1.当changea修改a的X值时把它改成a1.X就变成了2.
//ref参数
//如果A是结构类型,添加ref修饰符,通过引用传递变量
/* public static void ChangeA(ref A a)
{
a.X = 2;
}*/
//ChangeA(ref a1); 调用时也要添加ref,现在就与类类型一样了,结构也按引用传递
//把A作为类类型,使用ref修饰符,传递对引用的引用,允许分配一个新对象
public static void ChangeA(ref A a)
{
a.X = 2;
a = new A { X = 3 };
}
//在最后,重点对传递给方法的参数应用初始化要求,无论是按值还是按引用传递
}
class Fex4
{
//out参数
//如果方法返回多个值,可能类型还不同,怎么办?可以使用out关键字
static void ChangeB()
{
string input1 = Console.ReadLine();
int result1 = int.Parse(input1);
Console.WriteLine($"result:{result1}");
//TryParse声明为无论解析成功与否,都会返回一个bool类型,调用此方法后可在方法内部初始化变量
string input2 = Console.ReadLine();
if (int.TryParse(input2, out int result2))
{
Console.WriteLine($"result:{result2}");
}
else
{
Console.WriteLine("not a number");
}
}
//in参数 使参数设置为只读变量
//out允许返回参数指定的值,in则保证发送到方法中的数据不会更改
struct AValueType
{
public int data;
}
//使用in
static void CantChange(in AValueType a)
{
Console.WriteLine(a.data);
}
//使用in 有助于确保不更改内存,编译器还可以创建更好的优化代码
}
class Fex5
{
//可空类型
//引用类型的变量可以为空,那么值类型呢 当然不能
//可空类型是可以为空的值类型,只需要在类型后面添加?
static int x1 = 1;
static int? x2 = null;//int?不能直接分配给int需要转换一下
int x3 = (int)x2;
//枚举类型
//值类型-包含一组命名的常量,关键字为enum
public enum Color
{
Red = 0,
Green = 1,
Blue = 2,
}
//用枚举类型的名称作为前缀设置一个命名常量,来赋值
private static void ColorSamplis()
{
Color cl = Color.Red;
Console.WriteLine(cl);
}
//把多个选项分配给一个变量,不仅仅是一个枚举常量,必须是不同位的
public enum DayofWeek
{
Monday = 0x1,
Tuesday = 0x2,
Wednesday = 0x3,
Thursday = 0x4,
Friday = 0x5,
Saturday = 0x6,
Sunday = 0x7
}
DayofWeek mondayAndWednesday = DayofWeek.Monday | DayofWeek.Wednesday;
//Console.WriteLine(mondayAndWednesday)
//部分类
//partial 放在class/struct/interface关键字的前面
partial class SampleClass
{
public void MethodOne() { }
}
//public private protected internal abstract sealed new
//下回-继承
}
}
C#基础-5
最新推荐文章于 2024-10-12 10:28:10 发布