iis管理器添加网站,网站建设公司盈利,博客网站开发技术,wordpress主题名称文章目录 ObjectEqualsGetTypeToStringGetHashCode string逐字文本复合格式字符串字符串内插 StringBuilderStringBuilder 的工作原理StringBuilder提供的方法访问字符迭代字符查询字符 dynamic Object
支持 .NET 类层次结构中的所有类#xff0c;并为派生类提供低级别服务。… 文章目录 ObjectEqualsGetTypeToStringGetHashCode string逐字文本复合格式字符串字符串内插 StringBuilderStringBuilder 的工作原理StringBuilder提供的方法访问字符迭代字符查询字符 dynamic Object
支持 .NET 类层次结构中的所有类并为派生类提供低级别服务。 这是所有 .NET 类的最终基类它是类型层次结构的根。
简单来说它是万能的它是所有类型的父类。因为.NET 中的所有类都派生自 Object因此 Object 类中定义的每个方法都可用于系统中的所有对象。
在 Object 类中提供了 4 个常用的方法即 Equals、GetHashCode、GetType 以及 ToString 方法。
Equals
int a 1;
int b 1;
if (a.Equals(b))
{Debug.Log(111); -- 输出111
}Person a new Person();
Person b 1;
if (a.Equals(b))
{Debug.Log(111); -- 输出111
}Equals是相等判断与相同对于值类型的判断是否值相同而对于引用类型则判断是否引用相同。
GetType
用于获取当前实例的类型返回值为 System.Type 类型。GetType 方法不含任何参数是非静态方法。
使用Object.GetType()来返回对象的类型x.GetType()和typeof()的区别是GetType()是object的方法可以用于所有变量后以获取它们的类型。和typeof(xxx)内部只能放类型而不能放变量名。
ToString
将对象转换为其字符串表示形式使其适合显示。
上述三种方法是可以重载重写的。
GetHashCode
返回对象的哈希值每个对象的哈希值都是固定的。该方法不含有任何参数并且不是静态方法因此需要使用实例来调用该方法。由于该方法是在 Object 类中定义的因此任何对象都可以直接调用该方法。 string
字符串类型string表示零个或多个 Unicode 字符的序列。 比较特殊的是尽管string是引用类型但是使用来比较时却是值类型的比较。需要注意的是string是不可变类型这意味着每次我们修改字符串string的操作实际上都是创建了一个新的字符串。
逐字文本
使用关键字标识该字符串为逐字文本将不会识别转义符
Ahoy! cried the captain. // Ahoy! cried the captain.
c:\Docs\Source\a.txt // rather than c:\\Docs\\Source\\a.txt复合格式字符串
使用String.Format方法将变量复合到格式项内其中括号内的数字代表了对应的变量索引而:后面代表变量的指定类型。
String.Format(Name {0}, hours {1:hh}, name, DateTime.Now);多个相同索引也可以同时存在
string multiple String.Format(0x{0:X} {0:E} {0:N},Int64.MaxValue);
Console.WriteLine(multiple);
// The example displays the following output:
// 0x7FFFFFFFFFFFFFFF 9.223372E018 9,223,372,036,854,775,807.00字符串内插
使用$关键字标识字符串内插
string name Mark;
var date DateTime.Now;
// Composite formatting:
Console.WriteLine(Hello, {0}! Today is {1}, its {2:HH:mm} now., name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($Hello, {name}! Today is {date.DayOfWeek}, its {date:HH:mm} now.);更多用法请阅读官方文档,尤其是string类的方法尴尬的是string类的方法特别多但是String大多数情况下却被StringBuilder完爆) StringBuilder
使用命名空间System.Text来引入该类型
StringBuilder可以说是String的完全上位替代这是一个可变的字符串类。 可变性意味着创建类的实例后可以通过追加、删除、替换或插入字符对其进行修改。由于String每次修改时都需要产生一个新的字符串这也就导致了对其进行操作可能产生的一些内存消耗问题。所以对于需要操作的字符串我们会选择StringBuilder不过性能取决于字符串的大小、要为新字符串分配的内存量、执行代码的系统以及操作的类型。
请考虑在以下情况下使用 String 类
当代码对字符串进行的更改数较小时。 在这些情况下 StringBuilder 可能会提供微不足道的性能改进或者没有性能 String改进。执行固定数量的串联操作时尤其是字符串文本。 在这种情况下编译器可能会将串联操作合并到单个操作中。在生成字符串时必须执行广泛的搜索操作时。 类 StringBuilder 缺少搜索方法例如 IndexOf 或 StartsWith。 对于这些操作必须将 对象转换为 StringBuilder String 这可以抵消使用 StringBuilder的性能优势。 有关详细信息请参阅 在 StringBuilder 对象中搜索文本 部分。
请考虑在以下情况下使用 StringBuilder 类
如果预期代码在设计时对字符串进行未知数量的更改 (例如使用循环连接包含用户输入) 的随机数量的字符串时。预期代码对字符串进行大量更改时。
总的来说一些短平快的操作或者需要涉及串联字符串或是查询整个字符串的时候更适合String。如果一些需要频繁更改或者动态修改的字符串更适合StringBuilder
StringBuilder 的工作原理
StringBuilder是如何动态修改字符串长度的假设有一个字符串长度为16的stringBuilder如果我们需要Append成一个length 20的字符串那么首先StringBuilder会把字符串丢入这个长度为16的缓冲区当长度超过缓冲区的长度时则意味着需要更大的缓冲区则StringBuilder会找一个缓冲区大小翻一倍的新缓冲区现在是32了。然后把旧缓冲区的值复制过去并加入那些超过原长度而未被存入旧缓冲区的新字符。如果还是超过就重复上述过程直到存储完毕为止。如果超出了设定最大容量或者内存没有多余空间了则报错
public class Example
{public static void Main(){StringBuilder sb new StringBuilder();ShowSBInfo(sb);sb.Append(This is a sentence.);ShowSBInfo(sb);for (int ctr 0; ctr 10; ctr) {sb.Append(This is an additional sentence.);ShowSBInfo(sb);} }private static void ShowSBInfo(StringBuilder sb){foreach (var prop in sb.GetType().GetProperties()) {if (prop.GetIndexParameters().Length 0)Console.Write({0}: {1:N0} , prop.Name, prop.GetValue(sb));}Console.WriteLine();}
}
// The example displays the following output:
// Capacity: 16 MaxCapacity: 2,147,483,647 Length: 0
// Capacity: 32 MaxCapacity: 2,147,483,647 Length: 19
// Capacity: 64 MaxCapacity: 2,147,483,647 Length: 50
// Capacity: 128 MaxCapacity: 2,147,483,647 Length: 81
// Capacity: 128 MaxCapacity: 2,147,483,647 Length: 112
// Capacity: 256 MaxCapacity: 2,147,483,647 Length: 143
// Capacity: 256 MaxCapacity: 2,147,483,647 Length: 174
// Capacity: 256 MaxCapacity: 2,147,483,647 Length: 205
// Capacity: 256 MaxCapacity: 2,147,483,647 Length: 236
// Capacity: 512 MaxCapacity: 2,147,483,647 Length: 267
// Capacity: 512 MaxCapacity: 2,147,483,647 Length: 298
// Capacity: 512 MaxCapacity: 2,147,483,647 Length: 329
// Capacity: 512 MaxCapacity: 2,147,483,647 Length: 360StringBuilder提供的方法
可以进行单独的方法调用并忽略返回值如以下示例所示。
using System;
using System.Text;public class Example
{public static void Main(){StringBuilder sb new StringBuilder();sb.Append(This is the beginning of a sentence, ); sb.Replace(the beginning of , ); //替换所有字符A为字符Bsb.Insert(sb.ToString().IndexOf(a ) 2, complete );sb.Replace(,, .); Console.WriteLine(sb.ToString());}
}
// The example displays the following output:
// This is a complete sentence.可以在单个语句中调用一系列方法。 如果要编写链接连续操作的单个语句这可以很方便。 以下示例将上一示例中的三个方法调用合并到一行代码中。
using System;
using System.Text;public class Example
{public static void Main(){StringBuilder sb new StringBuilder(This is the beginning of a sentence, );sb.Replace(the beginning of , ).Insert(sb.ToString().IndexOf(a ) 2, complete ).Replace(,, .);Console.WriteLine(sb.ToString());}
}
// The example displays the following output:
// This is a complete sentence.访问字符
访问字符在我看来是StringBuilder的一大痛点。StringBuilder没有提供访问其内部字符的方法而想要访问其中的某个字符却没那么简单因为缓冲区的内存是不连续的如果想要找到某个字符我们就需要遍历整个缓冲区。因此较好的方法是通过ToString方法将其转化为String类型之后使用char[Index]去访问对应字符。
迭代字符
当迭代StringBuilder的字符的时候应当注意即使对于大型“区块” StringBuilder 对象使用 Chars[] 属性进行基于索引的访问一个或少量字符的性能影响可以忽略不计;通常这是 一个 O (n) 操作。 当迭代 StringBuilder 对象中的字符时会对性能造成显著的影响这是 O(n^2) (遍历n个字符*缓存区容量n操作。
因此当我们需要迭代StringBuilder的字符时较好的方法还是通过ToString方法将其转化为String类型之后使用char[Index]去访问对应字符。
查询字符
在StringBuilder中并没有提供查询字符的方法想实现查询字符也只能转为String然后用String.IndexOf或者String.StartWith方法查找对应的字符或字符串。
由于String和StringBuilder提供的方法太多因此此处无法深入推荐阅读官方文档 dynamic
最后稍微了解一下dynamic动态类型。dynamic本身也是一个Object。在大多数情况下dynamic 类型与 object 类型的行为类似。 具体而言任何非 Null 表达式都可以转换为 dynamic 类型。 dynamic 类型与 object 的不同之处在于编译器不会对包含类型 dynamic 的表达式的操作进行解析或类型检查。 编译器将有关该操作信息打包在一起之后这些信息会用于在运行时评估操作。 在此过程中dynamic 类型的变量会编译为 object 类型的变量。 因此dynamic 类型只在编译时存在在运行时则不存在。
dynamic的特殊就在于它是不会在编译时被解析的因此不会进行任何的安全检查。因此即使定义了错误的dynamic编译器也不会报错。而只有在运行时出现错误才会报错。
其次由于dynamic的本质是Object它也可以和任何类型进行隐式转换。而这也是它的最大优点。例如
dynamic x 10; //此时x为int
x x Hello; // x 现在是一个字符串
x x.ToUpper(); // x 仍然是一个字符串
x 8; // x 现在保存的是一个int类型的变量
x x * 8; // x现在仍然是int在上例中我们定义x为dynamic可以看出来它对应应当是int型然后我们将其转化为字符串然后对字符串进行操作。随后又把x赋值为了int类型的。x在整个程序中动态的变动它的类型。而这是var做不到的因为var关键字下编译器会自动地推断它的类型那它就是一个静态类一般没有显示转换的前提下我们是不能进行类型转换的。
如果只用静态类想实现则需要新创建其中设计到的静态类型对应的变量而如果想让静态类型变量x实现上述过程只会更加复杂
int x10;
String y x.ToString();
yyHello;
y y.ToUpper();
x 8;
x x* 8而dynamic的动态类型实际和某些脚本语言的变量性质是非常相似的。因此我们也使用dynamic类型来与脚本语言进行对接。