更新时间:2020/6/25
    
    首先恭喜你发现宝藏!!!:)
    
    
    
    
     小姐姐来源于网络😍😍
    
   
    
    
    便宜传送门:
   
    1.
    
     格式化输出
    
    
    2.
    
     字符串操作
    
    
    3.
    
     窗体控件
    
    
    4.窗体编程 –
    
     如何在一个窗体中使用另一个窗体中的控件
    
    
    5.窗体编程 –
    
     窗体设计多页面教程
    
    之前我想要搞多页面用了一个很笨的
    
     方法
    
    :)
   
    
    
    PART I 基础知识
   
    
    
    1、数据类型之间的相互转换
   
| 序号 | 方法 | 描述 | 
|---|---|---|
| 1 | ToBoolean | 如果可能的话,把类型转换为布尔型。 | 
| 2 | ToByte | 把类型转换为字节类型。 | 
| 3 | ToChar | 如果可能的话,把类型转换为单个 Unicode 字符类型。 | 
| 4 | ToDateTime | 把类型(整数或字符串类型)转换为 日期-时间 结构。 | 
| 5 | ToDecimal | 把浮点型或整数类型转换为十进制类型。 | 
| 6 | ToDouble | 把类型转换为双精度浮点型。 | 
| 7 | ToInt16 | 把类型转换为 16 位整数类型。 | 
| 8 | ToInt32 | 把类型转换为 32 位整数类型。 | 
| 9 | ToInt64 | 把类型转换为 64 位整数类型。 | 
| 10 | ToSbyte | 把类型转换为有符号字节类型。 | 
| 11 | ToSingle | 把类型转换为小浮点数类型。 | 
| 12 | ToString | 把类型转换为字符串类型。 | 
| 13 | ToType | 把类型转换为指定类型。 | 
| 14 | ToUInt16 | 把类型转换为 16 位无符号整数类型。 | 
| 15 | ToUInt32 | 把类型转换为 32 位无符号整数类型。 | 
| 16 | ToUInt64 | 把类型转换为 64 位无符号整数类型。 | 
使用示例:
int i = 75;
string str=i.ToString();
关于C# 数据类型及其 其他转换方法,详见:
    
    
    2、格式化输出数据
   
    格式化表示的一般格式:
    
     { N [ , M ] [ :格式码 ] }
    
    其中:
    
     ‘[]’
    
    表示可省
    
    
     N
    
    : 指定参数序列中的输出序号,比如{0} , {1}, {2}等。
    
    
     M
    
    : 指定参数输出的最小长度。 如果参数长度小于M,则空格填充;若大于等于M,则按实际长度输出;如果M为负,则左对齐,如果M为正,则右对齐;若未指定M,默认为0,如{1,5}表示将参数的值转换为字符串后按照5位右对齐输出。
    
    格式码:可选的格式化代码字符串如下表:
   
| 格式符 | 含义 | 示例 | 输出结果 | 
|---|---|---|---|
| C/c | 将数字按照金额形式输出 | Console.WriteLine(“{0:c}”, 5201314); | ¥5,201,314.00 | 
| D/d | 十进制整数,指定位数左补0 | Console.WriteLine(“{0:d9}”, 5201314); | 005201314 | 
| F/f | 固定位数小数,默认2位 | Console.WriteLine(“{0:f3}”, 5201314); | 5201314.000 | 
| N/n | 千分位,小数点后2位 | Console.WriteLine(“{0:n}”, 5201314); | 5,201,314.00 | 
| P/p | 百分比输出,整数千分位,小数点后2位 | Console.WriteLine(“{0:p}”, 5201314); | 520,131,400.00% | 
| X/x | 16进制输出,不够前补0 | Console.WriteLine(“{0:X8}”, 5201314); | 004F5DA2 | 
| # | 占位符,整数去掉左边无效0 | Console.WriteLine(“{0:#}”, 05201314); | 5201314 | 
    
    
    3、字符串(String) .VS. 字符数组(char[])
   
3.1 字符串(String)函数
int len=str.Length;//得到字符串的长度
string str1=str.Subsring(i,j);//取从i到j的子串
string str1=str.Remove(i,j);//删去从i到j的子串
string str1=str.Replace("ab","AB");//将str中的“ab”替换成“AB”
string[] sArray = str.Split(new string[] { " ", ",", "?", "->" }, StringSplitOptions.RemoveEmptyEntries);//根据string[]里面的内容分割字符串并去掉空项
int a=str.IndexOf(str1); //返回str1的第一个匹配项的位置
str2=String.Copy(str1); //将str1复制给str2
str.ToUpper();//将字符串中所有字符转换为大写
str.ToLower();//将字符串中所有字符转换为小写
str3=String.Join(str1,str2);//将str1与str2合并
double d= double.Parse(str);//将string转化为double
3.2 字符(char)函数
bool bur=char.IsDigit(myChar);//判断字符是否为数字
bool bur=char.IsLetter(myChar);//判断字符是否为字母
bool bur=char.IsPunctuation('?');//判断字符是否为标点符号
3.3 相互转换
char[] cArray=str.ToCharArray();//string转char
string str=new string(cArray);//char转string
    
    
    4、数组
   
4.1 数组的声明与初始化
int[] ca=new int[10]{1,2,3,4,5,6,7,8,9,10};//一维数组,下标从0到9
double[,] dou = new double[3, 3]{{1,2,3},{4,5,6},{7,8,9}};//二维数组
int[][] arrj=new int[3][];//交错数组 arrj[0]代表第一行
4.2 数组的方法与属性
int a=A.Length;  //只读 返回所有维数中元素个数的总数
int a=A.Rank; //只读,返回数组的维数
Array.Sort(A); //对一维数组从小到大排序
Array.Reverse(A); //反转数组
A.GetLowerBound(0); //得到数组指定维度的下限,括号中是数组的维度,0是1维
A.GetUpperBound(0); //得到数组指定维度的上限
Array.Clear(A); //清楚数组中所有元素的值,即把数组中所有元素设置为0、false或null
Array.Copy(A); //把一个数组复制给另一个数组
    
    
    5、窗体控件简介
   
    
    
    PART II 使用示例
   
    
    
    1、String操作
   
 	    static void Main(string[] args)
        {
            string s1 = "小鸟";
            string s2 = s1 + "飞翔";//“+”可以用来合并string
            Console.WriteLine("{0}", s2);// 小鸟飞翔
            string s3 = s2.Substring(1, 3);//取子string函数
            Console.WriteLine("{0}", s3);// 鸟飞翔
            s3 = s3.Replace("飞翔", "自由");//把“飞翔”换成“自由”
            Console.WriteLine("{0}", s3);// 鸟自由
            s3 = s3.Insert(2, "--");//在第三个字符处插入“--”
            Console.WriteLine("{0}", s3);// 鸟自--由
            bool isEqual = (s1 == s2);//判断s1和s2是否相等
            Console.WriteLine("{0}", isEqual);// False
            bool isContain = s2.Contains("鸟飞翔");//判断s2是否包含“鸟飞翔”
            Console.WriteLine("{0}", isContain );// True
            s1 = string.Format("小鸟飞了{0}公里",9);//把一个格式化字符串赋给s1
            Console.WriteLine("{0}", s1);// 小鸟飞了9公里
            Console.ReadLine();
        }
====================================================================
    
    
    2、类的创建与使用
   
	class Student//这是一个学生类
    {
        public string name;//公有属性name
        private int age;//私有属性age
        public void SetAge(int agevalue)//公有方法为age赋值
        {
            if (agevalue < 0)
                Console.WriteLine("年龄不能小于0");
            else age = agevalue;
        }
        public int GetAge()//公有方法查询年龄
        { return age; }
    }
    class Program
    {
        static void Main()
        {
            Student S1=new Student ();
            S1.SetAge(-20);
            Console.WriteLine("{0}", S1.GetAge());
            Console.Read();
        }
    }
 =============================================运行结果============
年龄不能小于0
0
    
    
    3、索引器
   
//一个参数的索引器
	class Book
    {//可把book理解成只有两个元素(书名,作者名)的集合
        private string Title;
        private string Author;
        //定义索引器:Index是字符串形参,value是隐式参数
        public string this[string index]
        {
            set//把value实参赋给Author或Title字段
            {
                if (index == "Author")
                    Author = value;
                else if (index == "Title")
                    Title = value;
            }
            get //取出Author或Title字段
            {
                if (index == "Author") return Author;
                if (index == "Title") return Title;
                return "Unknow";
            }
        }
    }
    //索引器的使用:对象名[index]
    class Program
    {
        static void Main()
        {
            Book book = new Book();
            book["Title"] = "家国天下";//调用set方法
            book["Author"] = "杨恒骏";
            Console.WriteLine(book["Title"]+" "+book["Author"]);//调用get方法
            Console.Read();
        }
    }
 =============================================运行结果============
 家国天下 杨恒骏
>>>>>>>>
//两个参数的索引器
 	class Books
    {
        private string[] Title=new string[100];//书名数组
        private string[] Author=new string[100];//作者名数组
        //定义索引器:i和index是它的两个形参,value是隐式参数
        public string this[int i,string index]
        {
            set//把value实参赋给Author或Title字段
            {
                if (index == "Author")
                    Author[i] = value;
                else if (index == "Title")
                    Title[i] = value;
            }
            get //取出Author或Title字段
            {
                if (index == "Author") return Author[i];
                if (index == "Title") return Title[i];
                return "Unknow";
            }
        }
    }
    //索引器的使用:对象名[i,index]
    class Program
    {
        static void Main()
        {
            Books books = new Books();
            books[0,"Title"] = "家国天下"; books[0,"Author"] = "杨恒骏";//设置第一条记录
            books[1, "Title"] = "乐生活"; books[1, "Author"] = "文玲";//设置第二条记录
            for(int i=0;i<2;i++)//访问记录
                Console.WriteLine(books[i,"Title"]+" "+books[i,"Author"]);//调用get方法
            Console.Read();
        }
    }
=============================================运行结果============
家国天下 杨恒骏
乐生活 文玲
    
    
    4、重载运算符
   
	class Complex
    {
        double r, i;//实部,虚部
        public Complex(double r0, double i0)//构造函数
        { r = r0; i = i0; }
        //重载加运算符,以满足复数运算
        public static Complex operator +(Complex c1, Complex c2)
        {
            Complex c = new Complex(0, 0);
            c.r = c1.r + c2.r;
            c.i = c1.i + c2.i;
            return c;
        }
    }
    class Program
    {
        static void Main()
        {
            Complex c1 = new Complex(2, 1);
            Complex c2 = new Complex(4, 3);
            Complex c3 = c1 + c2;//在此处前面设断点调试看结果
            Console.Read();
        }
    }
    
    
    5、打开或新建文件
   
    
    
    5.1 读文件
   
    注:打开文件的方法有好几种,这里只介绍了我喜欢的一种方法。
    
    注意,操作文件前要在文件头加上:
   
using System.IO;
//普通读文件
string FilePath=@"D:\MY WORK\C#\c#.txt";
//string FilePath="D:\\MY WORK\\C#\\c#.txt";
StreamReader sR = new StreamReader(FilePath);
string str = sR.ReadLine();
sR.Close();
//窗体读文件
OpenFileDialog file = new OpenFileDialog();
file.Title = "这是打开文件对话框的名字";
file.Filter = "文本文件(*.txt)|*.txt|DAT 文件(*.dat)|*.dat|所有文件(*.*)|*.*";
//file.DefaultExt = "txt";//缺省默认后缀名
file.ShowDialog();
//TextBox.Text = file.FileName;//保存文件路径至TextBox
StreamReader sR = new StreamReader(file.FileName);
string str = sR.ReadLine();
sR.Close();
    
    
    5.2 写文件
   
//普通写文件
string FilePath=@"D:\MY WORK\C#\c#.txt";
//string FilePath="D:\\MY WORK\\C#\\c#.txt";
StreamWriter WR = new StreamWriter(FilePath);
WR.Close();
//窗体写文件
string outputTif = null;
SaveFileDialog saveTifFileDialog = new SaveFileDialog();//打开保存文件对话框
saveTifFileDialog.OverwritePrompt = true;//询问是否覆盖
saveTifFileDialog.Filter = "*.txt|*.txt";
saveTifFileDialog.DefaultExt = "txt";//缺省默认后缀名
if (saveTifFileDialog.ShowDialog() == DialogResult.OK)
{
	outputTif = saveTifFileDialog.FileName;
	if (File.Exists(outputTif))
	{//如果文件存在,删除重建
		File.Delete(outputTif);
	}
	System.IO.Stream fileStream = saveTifFileDialog.OpenFile();//保存
    fileStream.Close();
}
StreamWriter WR = new StreamWriter(outputTif);
WR.Close();
    
    
    5.3 对文件的操作
   
 		static void Main()
        { //1 如果文件不存在,则创建它,添加数据"abc"后,关闭文件。 
            if (!File.Exists("d:/data.txt"))
                File.WriteAllText("d:/data.txt", "abc");
            //2 复制文件,在c盘产生了"复制data.txt"文件。         
            File.Copy("d:/data.txt", "d:/复制data.txt");
            //3 移动文件:产生了"复制data2.txt"文件,"复制data.txt"被删除。
            File.Move("d:/复制data.txt", "d:/英文小说/复制2data.txt");
            //4 删除文件。
            File.Delete("d:/data.txt");
            Console.Read();
        }
    
    
    PART III 常用功能实现
   
    
    
    1、辅助函数
   
    
    
    1.1 求象限角/正切函数
   
    我们常常要实现求一个点相对于另一个点的方位(象限角),这时就会用到正切函数,但是 C# 中 Math 库中自带的正切函数(
    
     Math.Atan(d)/Math.Atan2(dy,dx)
    
    )并不一定可以满足我们的需求,因为 arctan 函数只能求两个象限的象限角(忘记是1,4还是1,2象限了)所以在求象限角的时候要分情况来讨论:
    
    
    
    如上图所示:我们想要求 P[1/2/3/4] 相对于 P0 的方位,可以看到无论是测绘坐标系还是数学坐标系,象限的顺序虽然变了,但是算法并没有变,都是:
   
| 象限 | 特征 | 算法 | 
|---|---|---|
| I | dx>0; dy>0 | a=a | 
| II | dx<0; dy>0 | a=π-a | 
| III | dx<0; dy<0 | a=π+a | 
| IV | dx>0; dy<0 | a=2π-a | 
    其中:
    
     a = Math.Atan2(Math.Abs(dy), Math.Abs(dx));
    
    
    代码实现:
   
		/*此函数用于求象限角
         */ 
        public static double arctan(double dx, double dy)
        {
            double angle = 0;
            if(dx==0)
            {
                if(dy>0) angle=Math.PI*0.5;
                else     angle=Math.PI*1.5;
                return angle;
            }
            angle = Math.Atan2(Math.Abs(dy), Math.Abs(dx));
            if (dx < 0)
            {
                if (dy < 0) angle = Math.PI + angle;
                else        angle = Math.PI - angle;
            }
            else if (dy < 0) angle = 2 * Math.PI - angle;
            return angle;
        }
    
    
    1.2 导线方位角计算
   
    导线方位角计算就记住一个口诀就好了:
    
    
    
    代码实现:
   
		/* 此函数用于计算导线坐标方位角
         * 输入:frontAn: 前一条导线的方位角; ObserAn: 观测的角; bs: 左边(默认)还是右边
         * 输出:当前边的坐标方位角
         */
        public static Angle GetNext_FV(Angle frontAn, Angle ObserAn, string bs = "l")
        {
            bs = bs.ToLower();
            Angle PI = new Angle(Math.PI);
            if (bs != "r")//其实这里没必要取模,因为在重载加减里面已经考虑到角的取值为[0,2*PI)
                return (frontAn + ObserAn + PI) % new Angle(2 * PI);
            else
                return frontAn + ObserAn + PI;
        }
    
    
    1.3 生成随机数
   
		/* 辅助函数-求随机数
         * 可选输入:a 下界, b 上界
         */
        public static double getRandom(double a = 0, double b = 100)
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider r = new System.Security.Cryptography.RNGCryptoServiceProvider();
            r.GetBytes(bytes);
            double g = BitConverter.ToInt32(bytes, 0)/100.0;
            double c = b - a;
            return g % c + a;//得到在[a,b)范围内的随机数
        }
调用实例:
 Console.WriteLine("{0} {1}", getRandom(), getRandom(100,200));
由于后面想做的东西太多,写到一个博客里面会比较长,而且网页加载速度会变慢,所以,后面分开来写。
    
    
    2、坐标转换 四参数/正形变换/七参数
   
https://blog.csdn.net/Gou_Hailong/article/details/105362474
https://blog.csdn.net/Gou_Hailong/article/details/106960980
    
    
    3、曲线线路坐标计算
   
    
    
    4、求取圆心/球心坐标
   
    
    
    5、XYZ、BLH、NEU互转;高斯投影正反算
   
https://blog.csdn.net/Gou_Hailong/article/details/106938497
https://blog.csdn.net/Gou_Hailong/article/details/106960334
    
    
    6、闭合/附和 导线近似平差
   
    
    
    PART IV 对象/类
   
下面介绍几个类(有的是我自己写的,不妥之处,还望不吝赐教)
    
    
    1、矩阵类
   
    
    
    2、点类
   
    
    
    3、角类和里程类
   
    
    
    PART V 学习资源
   
    
    
    1.网站
   
1.MSDN
2.也许它叫C语言中文网
    
    
    2.书籍
   
1.C# 入门经典
链接:
https://pan.baidu.com/s/11Bibei5yoPv1jBB4EEddbg
提取码:m28l
2.C# 高级编程
链接:
https://pan.baidu.com/s/1xv1WdH-D-PA4SXsz2K8Ixw
提取码:3tuq
3.C# 图解教程
链接:
https://pan.baidu.com/s/1XKeuH7JWuAH1Ysg-iyggkQ
提取码:99nu
    
    
    PART VI 一些疑问
   
1.static void Main(string[] args)//括号里面的东西是什么意思?好像不要没什么影响
2.平差法 2.2 有跳不出循环的问题
3.曲线线路坐标计算 3 好像只能计算qr,qr?=hl;ql?=hr.已解决
    
    
    参考/引用 文章
   
[1] fonjames-CSDN博主:https://blog.csdn.net/fonjames/article/details/52839889  
[2] bcbobo21cn-CSDN博主:https://blog.csdn.net/bcbobo21cn/article/details/70336535?utm_source=app 
[3] OnLineStudy-CSDN博主:https://blog.csdn.net/OnLineStudy/article/details/5761388?utm_source=app 
[4] 杜_小妖-CSDN博主: https://blog.csdn.net/duyusean/article/details/73381502?utm_source=app 
[5] 百度经验: https://jingyan.baidu.com/article/f7ff0bfc7176492e26bb1309.html 
    
   
 
