关于c#:Unity-性能优化Shader分析处理函数ShaderUtilGetShaderGlobalKeywords用法

Unity 性能优化Shader剖析处理函数:ShaderUtil.GetShaderGlobalKeywords用法 点击封面跳转下载页面简介Unity 性能优化Shader剖析处理函数:ShaderUtil.GetShaderGlobalKeywords用法在Unity开发中,性能优化是一个十分重要的方面。一个常见的性能优化技巧是应用ShaderUtil.GetShaderGlobalKeywords函数来获取着色器的全局关键字。本文将介绍如何正确应用该函数,并提供一个实例代码来演示其用法。 什么是ShaderUtil.GetShaderGlobalKeywords函数?ShaderUtil.GetShaderGlobalKeywords是Unity引擎中的一个外部函数,它容许咱们获取一个着色器的全局关键字。全局关键字是在着色器中定义的一些开关,能够用来管制着色器的不同性能和成果。通过获取这些关键字,咱们能够在运行时动静地批改着色器的行为,从而实现更好的性能和成果。 如何应用ShaderUtil.GetShaderGlobalKeywords函数?因为ShaderUtil.GetShaderGlobalKeywords是一个internal标记的函数,咱们须要应用反射来调用它。上面是一个示例代码,展现了如何正确应用该函数: using System;using System.Reflection;using UnityEditor;using UnityEngine;public class ShaderUtilExample : MonoBehaviour{ private void Start() { // 获取以后激活的着色器 Shader shader = GetComponent<Renderer>().sharedMaterial.shader; // 应用反射调用GetShaderGlobalKeywords函数 MethodInfo getShaderGlobalKeywords = typeof(ShaderUtil).GetMethod("GetShaderGlobalKeywords", BindingFlags.Static | BindingFlags.NonPublic); string[] globalKeywords = (string[])getShaderGlobalKeywords.Invoke(null, new object[] { shader }); // 打印全局关键字 foreach (string keyword in globalKeywords) { Debug.Log(keyword); } }}在下面的示例代码中,咱们首先获取了以后激活的着色器。而后,咱们应用反射来调用GetShaderGlobalKeywords函数,并将以后着色器作为参数传递给它。函数返回一个蕴含全局关键字的字符串数组,咱们能够通过遍历数组来拜访每个关键字。 请留神,因为GetShaderGlobalKeywords是一个internal函数,它可能在将来的Unity版本中发生变化。因而,在应用该函数时,咱们须要小心解决,并确保在更新Unity版本时进行适当的测试和调整。 总结通过应用ShaderUtil.GetShaderGlobalKeywords函数,咱们能够获取着色器的全局关键字,从而实现更好的性能和成果。本文提供了一个应用反射调用该函数的示例代码,帮忙您了解如何正确应用它。在理论开发中,您能够依据本人的需要和场景,灵活运用这个函数来进行性能优化。 心愿本文对您在Unity性能优化方面有所帮忙!如果您有任何问题或疑难,请随时发问。 我的技术文章中可能存在的谬误向您示意诚挚的歉意。我致力确保提供精确牢靠的信息,但因为技术畛域的一直变动,谬误难以避免。如果您发现了谬误或有任何疑难,请与我分割。我将全力以赴纠正错误并提供更精确的信息。 再次向您示意最诚挚的歉意,我将更加审慎地审查和更新文章,以提供更好的浏览体验和精确的技术信息。 谢谢您的了解和反对。

September 11, 2023 · 1 min · jiezi

关于c#:C小白基础篇2-值类型字符串类型算数运算符赋值运算符关系运算符-等

 2.1 C#中的根本数据类型C#中变量的数据类型分为:值类型、援用类型、指针类型。 C#中值类型分为以下: 整型: byte、int 、short 、long byte的范畴 0-255 1字节 short的范畴 -32768 ---32767 2字节 int的范畴 -2147483648 -- 2147483647 4字节 long的范畴 -910^18 --- 910^18 8字节 浮点型: float -3.4x 10^38 ~ + 3.4 x 10^38 4个字节单精度 有精度损耗 0.0F 准确到小数点后大概7位 double (+/-)5.0 x 10-324 ~ (+/-)1.7 x 10308 8个字节双精度 有精度损耗 0.0D 准确到小数点后大概15~16位 十进制: decimal(准确) ±1.0 × 10^-28 到 ±7.9 × 10^28 16个字节 无损耗 0.0M 有效位数28位 布尔类型: bool (true、false) 字符类型: char 只能蕴含一个字符 ,‘\0’示意空字符 ...

September 10, 2023 · 2 min · jiezi

关于c#:Unity-编辑器资源导入处理函数-OnPostprocessTexture-深入解析与实用案例

Unity 编辑器资源导入处理函数 OnPostprocessTexture 用法 点击封面跳转下载页面简介在Unity中,咱们能够应用编辑器资源导入处理函数(OnPostprocessTexture)来自定义解决纹理资源的导入过程。这个函数是继承自AssetPostprocessor类的,通过重写这个函数,咱们能够在纹理资源导入实现后执行一些自定义的操作。 继承 AssetPostprocessor首先,咱们须要创立一个继承自AssetPostprocessor的脚本。这个脚本将用于解决纹理资源的导入过程。以下是一个示例代码: using UnityEditor;using UnityEngine;public class TexturePostprocessor : AssetPostprocessor{ void OnPostprocessTexture(Texture2D texture) { // 在这里编写自定义的纹理导入解决逻辑 }}在这个示例中,咱们创立了一个名为TexturePostprocessor的脚本,并重写了OnPostprocessTexture函数。 自定义纹理导入解决逻辑在OnPostprocessTexture函数中,咱们能够编写自定义的纹理导入解决逻辑。以下是五个示例代码,展现了不同的用法: 1. 设置纹理的类型为Spritevoid OnPostprocessTexture(Texture2D texture){ TextureImporter textureImporter = (TextureImporter)assetImporter; textureImporter.textureType = TextureImporterType.Sprite;}在这个示例中,咱们将纹理的类型设置为Sprite。这样,在导入纹理时,它将被主动设置为Sprite类型。 2. 设置纹理的PackageTag namevoid OnPostprocessTexture(Texture2D texture){ TextureImporter textureImporter = (TextureImporter)assetImporter; textureImporter.spritePackingTag = "MyPackage";}在这个示例中,咱们将纹理的PackageTag name设置为"MyPackage"。这样,在导入纹理时,它将被主动增加到名为"MyPackage"的纹理包中。 3. 设置纹理的MipMaps勾选void OnPostprocessTexture(Texture2D texture){ TextureImporter textureImporter = (TextureImporter)assetImporter; textureImporter.mipmapEnabled = true;}在这个示例中,咱们将纹理的MipMaps勾选设置为true。这样,在导入纹理时,它将生成MipMaps,以提供更好的渲染性能和品质。 4. 批改纹理的导入格局void OnPostprocessTexture(Texture2D texture){ TextureImporter textureImporter = (TextureImporter)assetImporter; textureImporter.textureFormat = TextureImporterFormat.RGBA32;}在这个示例中,咱们将纹理的导入格局设置为RGBA32。这样,在导入纹理时,它将以RGBA32格局存储。 5. 批改纹理的导入平台设置void OnPostprocessTexture(Texture2D texture){ TextureImporter textureImporter = (TextureImporter)assetImporter; textureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC2_RGBA8);}在这个示例中,咱们将纹理在Android平台上的导入设置批改为最大尺寸为2048,并且应用ETC2_RGBA8格局。这样,在导入纹理时,它将在Android平台上以指定的设置进行导入。 ...

September 6, 2023 · 2 min · jiezi

关于c#:小白C基础篇1-变量赋值运算符常量号的作用占位符的使用

<1>变量:存储数据的容器。 变量的命名规定: 必须以 “字母” _ 或 @ 符号结尾,不要以数字结尾前面能够跟任意 “字母” 、数字、下划线留神: (1) 你起的变量名不要与C#零碎中的关键字反复(2) 在C#中,大小写是敏感的(3) 同一个作用域中变量名不容许反复定义(4) 定义变量时,变量名要有意义给变量起名字的时候要满足的命名标准: Camel 骆驼命名标准。要求变量名首单词的首字母要小写,其余每个单词的首字母要大写。多用于给变量命名。<2>赋值运算符 = int = 1;//变量能够反复赋值,一旦给一个变量赋了新值,那么变量中的老值就不复存在了<3>常量const 类型 常量名 = 常量值 const int PI = 3.14;<4>+号的作用 连贯:当+号两边有一边是字符串的时候,+号就起到连贯的作用。相加:两边是数字的时候<5>占位符的应用 int n1 = 10;int n2 = 20;int n3 = 30;Console.WriteLine("{1},{0},{2}", n1, n2,n3);Console.WriteLine("第一个数字是:" + n1 + ",第二个数字是:" + n2 + ",第三个数字是:" + n3);Console.WriteLine($"第一个数字是{n1},第二个数字是{n2},第三个数字是{n3}");

September 3, 2023 · 1 min · jiezi

关于c#:C21天从入门到精通

download:C#21天从入门到精通C# 是一种古代的、通用的、面向对象的编程语言,它可能用来开发各种类型的应用程序,如桌面、Web、移动和游戏。要学习 C#,你需要了解它的基本语法、数据类型、控制流、方法、类和接口等概念。你还需要安装一个集成开发环境(IDE),如 Visual Studio 或 Visual Studio Code,来编写和运行你的代码。 为了帮助你入门 C#,我为你筹备了一篇示例代码文章,它将向你展示如何创建一个简略的 C# 控制台应用程序,它可能输入一句问候语,并接受用户输出的名字。这个程序将涉及以下内容: 使用 using 指令来引用命名空间使用 namespace 关键字来定义命名空间使用 class 关键字来定义类使用 static 关键字来定义动态成员使用 void 关键字来定义无返回值的方法使用 string 类型来示意文本数据使用 Console.WriteLine() 方法来输入文本到控制台使用 Console.ReadLine() 方法来从控制台读取文本使用 + 运算符来连接字符串使用 $ 字符来创建插值字符串上面是示例代码文章的内容: // C# 入门示例代码文章 // 本文将向你展示如何创建一个简略的 C# 控制台应用程序,它可能输入一句问候语,并接受用户输出的名字。 // 首先,咱们需要使用 using 指令来引用 System 命名空间,它蕴含了许多罕用的类和方法,如 Console 类。using System; // 而后,咱们需要使用 namespace 关键字来定义一个命名空间,它是一种组织代码的形式,可能避免命名冲突。// 咱们可能给命名空间起任意的名字,这里咱们使用 HelloWorld 作为示例。namespace HelloWorld{ // 接下来,咱们需要使用 class 关键字来定义一个类,它是一种封装数据和行为的对象。// 咱们可能给类起任意的名字,这里咱们使用 Program 作为示例。class Program{ // 而后,咱们需要使用 static 关键字来定义一个动态方法,它是一种不需要创建对象就可能间接调用的方法。 // 咱们可能给方法起任意的名字,这里咱们使用 Main 作为示例。 // Main 方法是一个非凡的方法,它是程序的入口点,也就是程序开始执行的地方。 // Main 方法必须有一个 void 类型的返回值,示意它不返回任何数据。 // Main 方法也必须有一个 string 类型的数组参数,示意它可能接受一些命令行参数。 static void Main(string[] args) { // 接下来,咱们可能在 Main 方法中编写咱们想要执行的代码。 // 首先,咱们使用 Console.WriteLine() 方法来输入一句问候语到控制台。 // Console.WriteLine() 方法可能接受一个 string 类型的参数,示意要输入的文本。 // 咱们可能间接使用双引号括起来的文本作为参数,也可能使用变量或表达式作为参数。 Console.WriteLine("Hello, world!"); // 而后,咱们使用 Console.WriteLine() 方法再次输入一句提醒语到控制台。 // 这次咱们使用了一个换行符 \n 来示意换行,这样可能让输入更好看。 Console.WriteLine("Please enter your name:\n"); // 接着,咱们使用 Console.ReadLine() 方法来从控制台读取用户输出的文本,并赋值给一个 string 类型的变量 name。 // Console.ReadLine() 方法没有参数,它会一直等待用户输出,直到用户按下回车键为止。 // 咱们可能给变量起任意的名字,这里咱们使用 name 作为示例。 string name = Console.ReadLine(); // 最初,咱们使用 Console.WriteLine() 方法再次输入一句问候语到控制台,这次咱们使用了用户输出的名字来定制问候语。 // 为了连接字符串,咱们可能使用 + 运算符,也可能使用 $ 字符来创建插值字符串,它可能让咱们在字符串中间接使用变量或表达式。 // 咱们使用了一个逗号和一个空格来分隔问候语和名字,这样可能让输入更天然。 Console.WriteLine("Hello, " + name + "!"); // 使用 + 运算符 Console.WriteLine($"Hello, {name}!"); // 使用插值字符串 // 这样,咱们就实现了一个简略的 C# 控制台应用程序,它可能输入一句问候语,并接受用户输出的名字。 // 咱们可能在 Visual Studio 或 Visual Studio Code 中运行和调试咱们的代码,看看成果如何。 }}}复制我心愿这篇示例代码文章对你有所帮助。如果你想要学习更多对于 C# 的内容,你可能参考以下的资源: ...

August 27, 2023 · 1 min · jiezi

关于c#:Winform-窗体缩放下-使用剪切板功能会出现页面闪动

问题Winform窗体,在首次应用剪切板性能时会呈现页面闪动。 起因应用了PresentionCore.dll里的Clipboard导致的,具体起因未知 解决应用其余办法进行剪切板性能,比方WindowAPI,Forms的Clipboard 演示代码MyClipboard.cs using System;using System.Runtime.InteropServices;namespace WindowsFormsApp2{ class MyClipboard { [DllImport("User32")] public static extern bool OpenClipboard(IntPtr hWndNewOwner); [DllImport("User32")] public static extern bool CloseClipboard(); [DllImport("User32")] public static extern bool EmptyClipboard(); [DllImport("User32")] public static extern bool IsClipboardFormatAvailable(int format); [DllImport("User32")] public static extern IntPtr GetClipboardData(int uFormat); [DllImport("User32", CharSet = CharSet.Unicode)] public static extern IntPtr SetClipboardData(int uFormat, IntPtr hMem); public static void FormsCopy() { System.Windows.Forms.Clipboard.SetDataObject("Forms"); } public static void PresentationCoreCopy() { System.Windows.Clipboard.SetDataObject("PresentationCore"); } public static void Win32Copy() { if (!OpenClipboard(IntPtr.Zero)) { return; } EmptyClipboard(); SetClipboardData(13, Marshal.StringToHGlobalUni("Win32")); CloseClipboard(); } }}Form1.cs ...

August 15, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Mask遮罩组件的介绍及使用

Unity UGUI的Mask(遮罩)组件的介绍及应用1. 什么是Mask组件?Mask(遮罩)组件是Unity UGUI中的一个重要组件,用于限度子对象的可见区域。通过设置遮罩组件,能够实现一些特殊效果,如显示局部图片、裁剪文本等。 2. Mask组件的工作原理Mask组件通过将子对象与遮罩对象进行比拟,只显示与遮罩对象重叠的局部,从而实现遮罩成果。遮罩对象能够是任意形态的UI元素,如Image、RawImage等。 3. Mask组件的罕用属性Show Mask Graphic:是否显示遮罩对象的图形。Mask Interaction:遮罩对象的交互方式,可抉择None、Visible Inside Mask和Visible Outside Mask。Alpha Cutoff:遮罩对象的透明度阈值,用于管制遮罩的显示范畴。4. Mask组件的罕用函数IsRaycastLocationValid:判断指定地位是否在遮罩范畴内。GetModifiedMaterial:获取通过遮罩解决后的材质。5. 示例代码示例1:显示局部图片using UnityEngine;using UnityEngine.UI;public class ImageMaskExample : MonoBehaviour{ public Image mask; public RawImage image; void Start() { mask.sprite = Resources.Load<Sprite>("MaskImage"); image.texture = Resources.Load<Texture>("Image"); image.transform.SetParent(mask.transform); mask.GetComponent<Mask>().showMaskGraphic = false; }}操作步骤: 创立一个Image对象作为遮罩对象,设置其形态为圆形。创立一个RawImage对象作为子对象,设置其图片为须要显示的图片。将遮罩对象和子对象增加到Canvas中。将子对象的父对象设置为遮罩对象。设置Mask组件的Show Mask Graphic属性为false。示例2:裁剪文本using UnityEngine;using UnityEngine.UI;public class TextMaskExample : MonoBehaviour{ public Text mask; public Text text; void Start() { mask.text = "Mask Text"; text.text = "Hello World"; text.transform.SetParent(mask.transform); mask.GetComponent<Mask>().showMaskGraphic = false; }}操作步骤: ...

July 10, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的GridLayoutGroup网格布局组件的介绍及使用

Unity UGUI的GridLayoutGroup(网格布局)组件的介绍及应用1. 什么是GridLayoutGroup组件?GridLayoutGroup是Unity UGUI中的一种布局组件,用于在UI界面中创立网格布局。它能够依据指定的行数、列数和间距主动排列子物体,使它们依照网格的模式排列。 2. GridLayoutGroup的工作原理GridLayoutGroup组件会依据指定的行数和列数,将子物体依照从左到右、从上到下的顺序排列。它还能够设置间距,管制子物体之间的距离。当子物体的数量超过网格的容量时,GridLayoutGroup会主动创立新的行或列来包容多余的子物体。 3. GridLayoutGroup的罕用属性Cell Size:指定每个单元格的大小。Spacing:指定子物体之间的间距。Start Corner:指定网格的起始角落。Start Axis:指定网格的起始轴线。Constraint:指定网格的束缚形式,能够是按行束缚或按列束缚。Constraint Count:指定每行或每列的最大子物体数量。4. GridLayoutGroup的罕用函数CalculateLayoutInputHorizontal():计算程度方向上的布局。CalculateLayoutInputVertical():计算垂直方向上的布局。SetLayoutHorizontal():设置程度方向上的布局。SetLayoutVertical():设置垂直方向上的布局。5. 示例代码示例1:创立一个2x2的网格布局using UnityEngine;using UnityEngine.UI;public class GridLayoutExample : MonoBehaviour{ public GridLayoutGroup gridLayout; public GameObject prefab; void Start() { gridLayout.constraint = GridLayoutGroup.Constraint.FixedColumnCount; gridLayout.constraintCount = 2; for (int i = 0; i < 4; i++) { Instantiate(prefab, transform); } }}操作步骤: 创立一个空的GameObject,并将GridLayoutExample脚本挂载下来。在Inspector面板中,将GridLayoutGroup组件拖拽到gridLayout变量上。创立一个预制体,将其拖拽到prefab变量上。运行游戏,能够看到预制体依照2x2的网格布局排列。注意事项: 须要提前创立好预制体,并将其拖拽到prefab变量上。示例2:创立一个3x3的网格布局,并设置间距using UnityEngine;using UnityEngine.UI;public class GridLayoutExample : MonoBehaviour{ public GridLayoutGroup gridLayout; public GameObject prefab; void Start() { gridLayout.constraint = GridLayoutGroup.Constraint.FixedColumnCount; gridLayout.constraintCount = 3; gridLayout.spacing = new Vector2(10, 10); for (int i = 0; i < 9; i++) { Instantiate(prefab, transform); } }}操作步骤: ...

July 10, 2023 · 2 min · jiezi

关于c#:Unity-UGUI的Canvas画布组件的介绍及使用

Unity UGUI的Canvas(画布)组件的介绍及应用1. 什么是Canvas组件?Canvas(画布)是Unity UGUI零碎中的一个重要组件,用于在屏幕上绘制UI元素。它是UI元素的容器,能够蕴含各种UI元素,如按钮、文本、图像等。Canvas组件提供了一种不便的形式来治理和渲染UI元素。 2. Canvas组件的工作原理Canvas组件通过渲染器将UI元素绘制到屏幕上。它应用层级构造来治理UI元素的显示程序,能够通过设置UI元素的层级来管制它们的显示程序。Canvas组件还能够设置渲染模式,包含屏幕空间、世界空间和摄像机空间等。 3. Canvas组件的罕用属性Render Mode(渲染模式):设置Canvas的渲染模式,包含屏幕空间、世界空间和摄像机空间等。Sorting Layer(排序层级):设置Canvas的排序层级,用于管制UI元素的显示程序。Order in Layer(层级程序):设置UI元素在排序层级中的显示程序。Pixel Perfect(像素完满):启用像素完满模式,能够确保UI元素在不同分辨率下的显示成果统一。Reference Pixels Per Unit(参考像素单位):设置参考像素单位,用于计算UI元素的大小和地位。4. Canvas组件的罕用函数SetRenderMode(RenderMode mode):设置Canvas的渲染模式。SetSortingLayerName(string name):设置Canvas的排序层级名称。SetOrderInLayer(int order):设置UI元素在排序层级中的显示程序。SetPixelPerfect(bool pixelPerfect):设置是否启用像素完满模式。SetReferencePixelsPerUnit(float pixelsPerUnit):设置参考像素单位。5. 示例代码示例1:创立一个屏幕空间的Canvasusing UnityEngine;using UnityEngine.UI;public class CanvasExample : MonoBehaviour{ void Start() { // 创立一个屏幕空间的Canvas GameObject canvasObject = new GameObject("Canvas"); Canvas canvas = canvasObject.AddComponent<Canvas>(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; // 创立一个UI元素 GameObject textObject = new GameObject("Text"); textObject.transform.SetParent(canvas.transform); Text text = textObject.AddComponent<Text>(); text.text = "Hello World!"; }}操作步骤: 创立一个空的GameObject,并将脚本挂载到该GameObject上。在Start函数中,创立一个屏幕空间的Canvas。创立一个UI元素,并将其设置为Canvas的子物体。设置UI元素的文本内容为"Hello World!"。示例2:创立一个世界空间的Canvasusing UnityEngine;using UnityEngine.UI;public class CanvasExample : MonoBehaviour{ void Start() { // 创立一个世界空间的Canvas GameObject canvasObject = new GameObject("Canvas"); Canvas canvas = canvasObject.AddComponent<Canvas>(); canvas.renderMode = RenderMode.WorldSpace; // 创立一个UI元素 GameObject textObject = new GameObject("Text"); textObject.transform.SetParent(canvas.transform); Text text = textObject.AddComponent<Text>(); text.text = "Hello World!"; }}操作步骤: ...

July 10, 2023 · 2 min · jiezi

关于c#:Unity-UGUI的ScrollRect滚动视图组件的介绍及使用

Unity UGUI的ScrollRect(滚动视图)组件的介绍及应用1. 什么是ScrollRect组件?ScrollRect(滚动视图)是Unity UGUI中的一个罕用组件,用于在UI界面中创立可滚动的区域。通过ScrollRect组件,能够实现在无限的空间内显示大量的内容,并且能够通过滑动手势来浏览内容。 2. ScrollRect组件的工作原理ScrollRect组件通过将内容搁置在一个可滚动的矩形区域内,而后通过拖动或滑动手势来扭转内容的显示地位。ScrollRect组件蕴含一个Viewport(视口)和一个Content(内容)两个子对象,Viewport用于限度Content的显示范畴,而Content则蕴含了理论的内容。 3. ScrollRect组件的罕用属性Content:用于搁置理论的内容的RectTransform对象。Horizontal:是否容许程度方向的滚动。Vertical:是否容许垂直方向的滚动。Movement Type:滚动的类型,可选的类型有:Unrestricted(不受限制)、Elastic(弹性)、Clamped(限度)。Inertia:是否启用惯性滚动。Deceleration Rate:惯性滚动的加速率。Scroll Sensitivity:滚动的灵敏度。4. ScrollRect组件的罕用函数ScrollTo:滚动到指定地位。StopMovement:进行滚动。OnBeginDrag:开始拖拽时调用的函数。OnDrag:拖拽过程中调用的函数。OnEndDrag:完结拖拽时调用的函数。5. 示例代码示例1:根本的滚动视图using UnityEngine;using UnityEngine.UI;public class ScrollRectExample : MonoBehaviour{ public ScrollRect scrollRect; void Start() { // 设置Content的大小 RectTransform content = scrollRect.content; content.sizeDelta = new Vector2(0, 1000); // 设置滚动视图的滚动范畴 scrollRect.verticalNormalizedPosition = 1; }}操作步骤: 创立一个空的GameObject,并增加ScrollRect组件。在Hierarchy面板中选中ScrollRect对象,将Content对象拖拽到ScrollRect的Content属性中。将示例代码增加到ScrollRectExample脚本中,并将ScrollRect对象拖拽到scrollRect属性中。运行游戏,能够看到滚动视图中的内容能够通过滑动手势进行滚动。示例2:限度滚动范畴using UnityEngine;using UnityEngine.UI;public class ScrollRectExample : MonoBehaviour{ public ScrollRect scrollRect; void Start() { // 设置Content的大小 RectTransform content = scrollRect.content; content.sizeDelta = new Vector2(0, 1000); // 设置滚动视图的滚动范畴 scrollRect.verticalNormalizedPosition = 1; scrollRect.movementType = ScrollRect.MovementType.Clamped; }}操作步骤: ...

July 10, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Dropdown下拉菜单组件的介绍及使用

Unity UGUI的Dropdown(下拉菜单)组件的介绍及应用1. 什么是Dropdown组件?Dropdown(下拉菜单)是Unity UGUI中的一个罕用组件,用于在用户点击或抉择时显示一个下拉菜单,提供多个选项供用户抉择。 2. Dropdown组件的工作原理Dropdown组件由两局部组成:一个可点击的按钮和一个下拉菜单。当用户点击按钮时,下拉菜单会开展,显示所有选项。用户能够通过点击选项来进行抉择。 3. Dropdown组件的罕用属性Options:下拉菜单中的选项列表。Caption Text:按钮上显示的文本。Template:下拉菜单的模板。Item Text:下拉菜单中选项的文本。On Value Changed:当抉择的值发生变化时触发的事件。4. Dropdown组件的罕用函数ClearOptions():清空下拉菜单中的选项。AddOptions(List<string> options):向下拉菜单中增加选项。SetValueWithoutNotify(int value):设置以后抉择的值,但不触发事件。5. 示例代码示例1:创立一个简略的下拉菜单using UnityEngine;using UnityEngine.UI;public class DropdownExample : MonoBehaviour{ public Dropdown dropdown; void Start() { dropdown.ClearOptions(); dropdown.AddOptions(new List<string> { "Option 1", "Option 2", "Option 3" }); }}操作步骤: 创立一个空物体,并将Dropdown组件增加到该物体上。将DropdownExample脚本增加到该物体上。在Inspector面板中,将Dropdown组件的援用拖拽到DropdownExample脚本的dropdown字段上。运行游戏,下拉菜单中将显示"Option 1"、"Option 2"和"Option 3"三个选项。注意事项: 在Start函数中增加选项,确保在游戏开始时下拉菜单曾经初始化。示例2:获取以后抉择的值using UnityEngine;using UnityEngine.UI;public class DropdownExample : MonoBehaviour{ public Dropdown dropdown; void Start() { dropdown.ClearOptions(); dropdown.AddOptions(new List<string> { "Option 1", "Option 2", "Option 3" }); } public void OnDropdownValueChanged(int value) { Debug.Log("Selected option: " + dropdown.options[value].text); }}操作步骤: ...

July 10, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Scrollbar滚动条组件的介绍及使用

Unity UGUI的Scrollbar(滚动条)组件的介绍及应用一、什么是Scrollbar组件?Scrollbar组件是Unity中UGUI零碎提供的一种UI组件,次要用于在UI界面中提供滚动条性能,使用户能够通过滚动条来查看超出屏幕范畴的内容。 二、Scrollbar组件是如何工作的?Scrollbar组件的工作原理次要是通过扭转滚动条的地位来扭转关联的内容的显示地位。当用户拖动滚动条时,Scrollbar组件会依据滚动条的地位计算出一个值(范畴在0到1之间),而后将这个值传递给关联的内容,由内容依据这个值来扭转本人的显示地位。 三、Scrollbar组件的罕用属性Scrollbar组件的罕用属性次要有以下几个: Direction:滚动条的方向,能够是从左到右、从右到左、从下到上、从上到下。Value:滚动条的以后值,范畴在0到1之间。Size:滚动条滑块的大小,范畴在0到1之间,值越大,滑块越大。NumberOfSteps:滚动条的步进值,如果设置为0,则滚动条能够平滑滚动;如果设置为大于0的值,则滚动条会依照步进值来滚动。四、Scrollbar组件的罕用函数Scrollbar组件的罕用函数次要有以下几个: OnValueChanged:当滚动条的值扭转时触发的事件。Rebuild:从新构建滚动条。LayoutComplete:当滚动条的布局实现时触发的事件。GraphicUpdateComplete:当滚动条的图形更新实现时触发的事件。五、Scrollbar组件的应用示例上面将通过5个示例来介绍如何应用Scrollbar组件。 示例1:创立一个简略的Scrollbar// 创立一个ScrollbarScrollbar scrollbar = new GameObject("Scrollbar").AddComponent<Scrollbar>();// 设置滚动条的方向scrollbar.direction = Scrollbar.Direction.LeftToRight;// 设置滚动条的值scrollbar.value = 0.5f;// 设置滚动条滑块的大小scrollbar.size = 0.1f;示例2:监听Scrollbar的值扭转事件// 创立一个ScrollbarScrollbar scrollbar = new GameObject("Scrollbar").AddComponent<Scrollbar>();// 增加值扭转事件的监听scrollbar.onValueChanged.AddListener((value) => { Debug.Log("Scrollbar value changed: " + value);});示例3:设置Scrollbar的步进值// 创立一个ScrollbarScrollbar scrollbar = new GameObject("Scrollbar").AddComponent<Scrollbar>();// 设置滚动条的步进值scrollbar.numberOfSteps = 10;示例4:从新构建Scrollbar// 创立一个ScrollbarScrollbar scrollbar = new GameObject("Scrollbar").AddComponent<Scrollbar>();// 从新构建滚动条scrollbar.Rebuild(CanvasUpdate.Prelayout);示例5:监听Scrollbar的布局实现事件和图形更新实现事件// 创立一个ScrollbarScrollbar scrollbar = new GameObject("Scrollbar").AddComponent<Scrollbar>();// 增加布局实现事件的监听scrollbar.onValueChanged.AddListener(() => { Debug.Log("Scrollbar layout complete.");});// 增加图形更新实现事件的监听scrollbar.onValueChanged.AddListener(() => { Debug.Log("Scrollbar graphic update complete.");});六、注意事项在应用Scrollbar组件时,须要留神以下几点: Scrollbar组件的值范畴是0到1,不要设置超出这个范畴的值。如果要使Scrollbar能够平滑滚动,须要将步进值设置为0。在监听Scrollbar的值扭转事件时,须要留神不要在事件处理函数中再次批改Scrollbar的值,否则可能会导致有限循环。七、参考资料Unity官网文档:ScrollbarUnity官网教程:UGUI Scrollbar

July 8, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Toggle复选框组件的介绍及使用

Unity UGUI的Toggle(复选框)组件的介绍及应用1. 什么是Toggle组件?Toggle(复选框)是Unity UGUI中的一个罕用组件,用于实现复选框的性能。它能够被选中或勾销选中,并且能够代码通过其制控状态。 2. Toggle组件的工作原理组Toggle件由两个局部组成:背景记标和。景背用于显示复选框的外观示意于用记标,复选框的选中状态。当被件组Toggle点击时,它会主动切换选中状态,并触发相应的事件。 3. Toggle组件的罕用属性Is On示意:Toggle组件的当选状态代码通过能够,管制。Transition:示意组Toggle件的过渡成果,包含None、Color Tint、Sprite Swap等选项。Graphic:示意Toggle组件的背景图像。GroupToggle示意:件组所属Toggle的Group组。On Value Changed:示意Toggle组件选中状态扭转时触发的事件。 ## 4. Toggle组件的罕用函数 void Toggle():切换组Toggle的件选中状态。void OnClickPointer(PointerEventData eventData):解决Toggle组件的点击事件。5. 示例代码1 示例 创立一个简略的Toggle组件创立一个对象Canvas,并在Canvas下创立Toggle一个对象。设置组件Toggle的Is On属性为true。运行游戏,点击Toggle组件,察看Toggle组件的选中状态是否扭转。示例2:应用代码管制Toggle组件选的中状态创立一个Canvas对象在,并Canvas下创立一个Toggle对象。在脚本中获取Toggle组件的援用。在代码中应用Toggle组件的Is On属性管制Toggle组件的选中状态。using UnityEngine;using UnityEngine.UI;public class ToggleExample : MonoBehaviour{ public Toggle toggle; private void Start() { toggle =.isOn true; }}示例3:应用Toggle组件的事件创立一个Canvas对象,并在下Canvas创立Toggle一个对象。在脚本中增加一个办法,用于解决Toggle组件的选中状态扭转事件。将该办法绑定到Toggle组件的On Value Changed事件上。using UnityEngine;using UnityEngine.UI;public class ToggleExample : MonoBehaviour{ public Toggle toggle; private void Start() { toggle.onValueChanged.AddListener(OnToggleValueChanged); } private void OnToggleValueChanged(bool isOn) { Debug.Log("Toggle is " + (isOn ? "on" : "off")); }}示例4:应用Toggle组件的过渡成果创立一个Canvas对象,并在Canvas下创立一个Toggle对象。设置Toggle组件的Transition属性为Colorint T。设置Toggle组件的Graphic属性为一个背景图像。运行游戏,察看Toggle组件的过渡成果。示例5:应用Toggle组件的Toggle Group创立一个Canvas对象,并在Canvas下创立两Toggle个对象。创立一个ToggleGroup对象,并将两个Toggle对象的Group属性为设置该ToggleGroup对象。运行游戏,察看Toggle组件的选中状态是否互斥。注意事项Toggle组件必放须在Canvas对象下能力失常显示。Toggle组件的选中状态能够通过代码管制也,能够通过点击切换。Toggle组件的选状态中扭转时会触发相应的事件。参考资料Unity官网文档:Toggle

July 8, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Slider滑动条件组的介绍及使用

Unity UGUI的Slider(滑动条)件组的介绍及应用1. 什么是Slider组件?Slider(滑动条)是Unity UGUI中的一种罕用UI组件用,于在用户界面中实现滑动抉择的性能。通过拖动滑块,用户能够抉择一个数值范畴的内值。 2. Slider组件的工作原理Slider组件由两局部组成:滑动区域和滑块。滑动区域用于显示滑动条的背景,而滑块则示意以后的数值地位。用户能够通过拖动滑块来扭转数值。 3. Slider组件的罕用属性Min Value(最小值):滑动的条值小最 **。Max Value最(大)值:滑动条的最值大。Value(以后值):滑动条的以后值。Whole Numbers(只容许整值数整抉择许允只是否:)数。Direction(方向):滑动条的方向,能够是程度或垂直。Handle Slide Area(滑块)域区动滑:滑块能够在滑动区域内滑动。Handle Slide Range(滑块滑动范畴):滑块在动滑区域内滑的动范畴。4. Slider组常的件用函数SetValueWithoutNotify(float value):设置滑动条的以后值,但不触发OnValueChanged事件。OnValueChanged(UnityAction<float> action):当滑动条的值发生变化时触发的事件。5. 示例代码示例1:根本应用using UnityEngine;using UnityEngine.UI;public class SliderExample : MonoBehaviour{ public Slider slider; private void Start() { slider.onValueChanged.AddListener(OnSliderValueChanged); } private void OnSliderValueChanged(float value) { Debug.Log("Slider value changed: " + value); }}操作步骤: 创立一个空物体,并将Slider组件增加到该物体上2。. 将SliderExample脚本增加到该物体上。在Inspector面板中,将SliderExample脚本的slider字段关联到Slider组件。运行游戏,拖动滑块,察看控制台输入。注意事项: 通过监听Slider的onValueChanged事件,能够在滑动条的值发生变化时执行自定义的逻辑。示例2:限度数值范畴using UnityEngine;using UnityEngine.UI;public class SliderExample : MonoBehaviour { public Slider slider; private void Start() { slider.minValue = 0; slider.maxValue = 100; slider.wholeNumbers = true; }}操作步骤: ...

July 8, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的InputField输入框组件的介绍及使用

UGUI的InputField(输入框)组件的介绍及应用1. 什么是UGUI的InputField组件?UGUI的InputField组件是Unity中的一个用户界面组件,用于接管用户的输出。它能够用于创立文本输入框、明码输入框等性能。 2. UGUI的InputField组件的工作原理UGUI的InputField组件通过监听用户的输出事件,用户将输出的内容保留在一个字符串中,并将该字符串显示在输入框中。用户能够通过键盘输入、鼠标点击等形式进行输出。 .3 UGUI的Input组Field件的罕用属性text: 输入框中显示的文本内容。placeholder: 输入框中未输出内容时显示的占位符文本。characterLimit: 输入框中可输出的最大数字符限度。 -contentType: 输入框中可输出的内容类型,如整数、小数、明码等。onValueChanged: 输入框内容扭转时触发的事件。4. UGUI的InputField组件的函数用常- ActivateInputField(): 激活输入框,使其能够接管用户输出。 DeactivateInputField(): 勾销激活输入框,使其无奈接管用户输出。OnSubmit(): 用户按下回车键或点击提交按钮时触发的事件。5. 示例代码示例1:创立一个简略的文本输入框using UnityEngine;using UnityEngine.UI;public class Example : MonoBehaviour{ public InputField inputField; private void Start() { inputField.onValueChanged.AddListener(OnInputValueChanged); } private void OnInputValueChanged(string value) { Debug.Log("输入框内容扭转:" + value); }}操作步骤: 创立一个空物体,并将脚本Example挂载到该物体上。在场景中创立一个InputField对象,并将其拖拽到Example脚本的inputField字段中。运行游戏,输入框中输出内容,察看控制台输入。事留神项: 示例代码中的OnInputValueChanged办法会在输入框内容扭转时被调用。示例2:限度输入框中的字符数using UnityEngine;using UnityEngine.UI;public class Example : MonoBehaviour{ public InputField inputField; public int maxCharacterLimit = 10; private void Start() { inputField.characterLimit = maxCharacterLimit; }}操作步骤:1. 创立一个空物体,并将脚本Example挂载到物该体上。 在场景中创立一个InputField对象,并将其拖拽到Example脚本的inputField字段中。将maxCharacterLimit的值设置为想要限度的最大字符数。运行游戏,输入框中输出超过最大字符数的内容,察看输入框中的字符数是否受限制。注意事项: ...

July 8, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Image图片组件的介绍及使用

UGUI的Image(图片)组件的介绍及应用1. 什么是UGUI的Image(图片)组件?UGUI的Image(图片)组件是Unity引擎中的一种UI组件,用于显示2D图像。它提供了一种简略而灵便的形式来在游戏中加载和显示图片。 2. 为什么要应用UGUI的Image(图片)组件?应用UGUI的Image组件能够不便地在游戏中展现各种图片资源,比方角色头像、道具图标等。它具备以下长处: 易用性:UGUI的Image组件提供了简略易懂的接口,使得开发者能够轻松地加载和显示图片。灵活性:能够通过设置Image组件的属性,如色彩、透明度等,来实现各种成果的图片展现。性能优化:UGUI的Image组件反对图片的批量渲染,可能高效地解决大量的图片资源。3. 如何应用UGUI的Image(图片)组件?上面是应用UGUI的Image组件的五个具体例子代码,并附带操作步骤和注意事项: 示例代码1:加载并显示图片using UnityEngine;using UnityEngine.UI;public class ImageExample : MonoBehaviour{ public Image image; public Sprite sprite; private void Start() { image.sprite = sprite; }}操作步骤: 创立一个空对象,并将该脚本挂载到该对象上。在场景中增加一个Canvas对象,并将Canvas的Render Mode设置为Screen Space - Overlay。在Canvas下创立一个Image对象,并将Image组件拖拽到脚本的image字段上。将要显示的图片资源拖拽到脚本的sprite字段上。运行游戏,图片将会在场景中显示进去。注意事项: 确保图片资源曾经导入到Unity工程中。确保Canvas的Render Mode正确设置,以保障图片在正确的地位显示。示例代码2:设置图片的色彩using UnityEngine;using UnityEngine.UI;public class ImageExample : MonoBehaviour{ public Image image; private void Start() { image.color = Color.red; }}操作步骤: 创立一个空对象,并将该脚本挂载到该对象上。在场景中增加一个Canvas对象,并将Canvas的Render Mode设置为Screen Space - Overlay。在Canvas下创立一个Image对象,并将Image组件拖拽到脚本的image字段上。运行游戏,图片的色彩将会变为红色。注意事项: 能够通过设置image.color属性来扭转图片的色彩。色彩值能够应用Unity的Color构造体来示意。示例代码3:设置图片的透明度using UnityEngine;using UnityEngine.UI;public class ImageExample : MonoBehaviour{ public Image image; private void Start() { Color color = image.color; color.a = 0.5f; image.color = color; }}操作步骤: ...

July 8, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Text文本组件的介绍及使用

UGUI的Text(文本)组件的介绍及应用什么是UGUI的Text(文本)组件?UGUI(Unity Graphic User Interface)是Unity引擎的一套用户界面零碎,而Text(文本)组件是UGUI中用于在游戏界面中显示文本的组件。该组件能够用于显示游戏中的文字、数字、标签等信息。 为什么要应用UGUI的Text(文本)组件?应用UGUI的Text组件能够在游戏界面中实时显示文字信息,不便玩家理解游戏的状态、交互信息等。 应用UGUI的Text(文本)组件的步骤:在Unity编辑器中创立一个Canvas对象,并为Canvas增加一个Text组件。 重点步骤: 在Hierarchy面板中右键点击Canvas对象,抉择“UI -> Text”创立一个Text子对象。设置Text组件的款式属性。 重点步骤: 在Inspector面板中抉择Text组件,设置其地位、大小、字体、字号、色彩等款式属性。通过脚本管制Text组件显示的文本内容。 重点步骤: 在脚本中获取Text组件的援用,并通过代码管制其显示的文本内容。动静更新文本内容。 重点步骤: 依据需要,能够通过代码实现文本的动静更新,比方显示计时器、得分等实时变动的信息。增加动画成果。 重点步骤: 依据游戏的需要,能够为Text组件增加适当的动画成果,加强用户体验。例子代码:在Canvas中创立一个Text组件: 在Hierarchy面板中右键点击Canvas对象,抉择“UI -> Text”创立一个Text子对象。 设置Text组件的款式属性: 在Inspector面板中抉择Text组件,设置其地位、大小、字体、字号、色彩等款式属性。 通过脚本管制Text组件显示的文本内容: using UnityEngine;using UnityEngine.UI;public class ExampleScript : MonoBehaviour{ public Text textComponent; private void Start() { textComponent.text = "Hello, World!"; }}动静更新文本内容: using UnityEngine;using UnityEngine.UI;public class ExampleScript : MonoBehaviour{ public Text textComponent; private int score = 0; private void Update() { score++; textComponent.text = "Score: " + score.ToString(); }}增加动画成果: ...

July 8, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的Button组件的介绍及使用

UGUI的Button(按钮)组件的介绍及应用1. 什么是UGUI的Button组件?UGUI(Unity GUI)是Unity引擎中的一套用户界面零碎,Button(按钮)是其中的一个罕用组件。Button组件能够用于创立可交互的按钮,用户点击按钮时能够触发相应的事件。 2. Button组件工的作原理Button组件通过检测用户的点击事件来触发相应的操作。当用户点击按钮时,Button组件会检测到点击事件,并执行相应的操作,如比调用指定的函数或扭转按钮的状态。 3. Button组件的罕用属性Interactable(可交互):设置按钮是否可交互。如果设置为false,按钮将无奈被点击。Transition(过渡成果):设置按钮的过渡成果,包含色彩、缩放、透明度等。Normal Color(失常状态色彩):设置按钮在失常状态下的色彩。Highlighted Color高(亮状态色彩):设置按钮在高亮状态下的色彩。Pressed Color(按下状态色彩):设置按钮在按下状态下的色彩。Disabled Color(禁用状态色彩):设置按钮在禁用状态下的色彩。4. Button组件的罕用函数onClick.AddListener():为按钮增加点击事件的监听器。onClick.Remove()Listener:移除按钮的点击事件监听器。onClick.Invoke():手动触发按钮的点击事件。5. 示例代码示例1:创立一个简略的按钮using UnityEngine;using UnityEngine.UI;public class ButtonExample : MonoBehaviour{ public Button button; void Start() { button.onClick.AddListener(OnClick); } void OnClick() { Debug.Log("Button clicked!"); }}操作步骤: 创立一个空物体,并将脚本ButtonExample挂载到该物体上。在场景中创立一个按钮,并将该按钮的援用赋值给button变量。运行游戏,点击按钮,控制台将输入"Button clicked!"。注意事项: 确保按钮的OnClick事件曾经绑定到ButtonExample脚本的OnClick函数。示例2:扭转按钮的色彩using UnityEngine;using UnityEngine.UI;public class ButtonExample : MonoBehaviour{ public Button button; void Start() { button.onClick.AddListener(OnClick); } void OnClick() { button.image.color = Color.red; }}操作步骤: 创立一个空物体,并将脚本ButtonExample挂载到该体物上。在场景中创立一个按钮,并将该按钮的援用赋值给button变量。运行游戏,点击按钮,按钮的色彩将变为红色。注意事项: 确保按钮的OnClick事件曾经绑定到ButtonExample脚本的OnClick函数。示例3:禁用按钮using UnityEngine;using UnityEngine.UI;public class ButtonExample : MonoBehaviour{ public Button button; void Start() { button.onClick.AddListener(OnClick); } void OnClick() { button.interactable = false; }}操作步骤: ...

July 7, 2023 · 1 min · jiezi

关于c#:Unity-UGUI的所有组件的介绍及使用

Unity UGUI的所有组件的介绍及应用本文将介绍Unity UGUI中的各个组件,包含它们的具体介绍、用处 1. Text(文本)介绍:Text组件用于在UI界面上显示文本内容。用处:罕用于显示UI界面的题目、按钮标签、提示信息等。2. Image(图片)介绍:Image组件用于在UI界面上显示图片。用处:罕用于显示角色头像、道具图标、背景图片等。3. Button(按钮)介绍:Button组件用于创立可交互的按钮。用处:罕用于触发UI界面的按钮点击事件,例如开始游戏、关上菜单等。4. InputField(输入框)介绍:InputField组件用于接管用户的输出。用处:罕用于接管用户的文本输出,例如用户名、明码等。5. Slider(滑动条)介绍:Slider组件用于显示和管制数值的滑动条。用处:罕用于调整音量、进度条等须要间断数值调整的场景。6. Toggle(复选框)介绍:Toggle组件用于创立复选框。用处:罕用于设置选项的开关状态,例如音效开关、全屏模式等。7. Scrollbar(滚动条)介绍:Scrollbar组件用于管制可滚动内容的滚动条。用处:罕用于显示过长的文本内容或列表,使用户能够滑动查看全部内容。8. Dropdown(下拉菜单)介绍:Dropdown组件用于创立下拉菜单。用处:罕用于提供多个选项供用户抉择,例如游戏难度抉择、语言选择等。9. ScrollRect(滚动视图)介绍:ScrollRect组件用于创立可滚动的视图区域。用处:罕用于显示大量内容,使用户能够高低或左右滑动查看。10. Canvas(画布)介绍:Canvas组件用于创立UI元素的容器。用处:罕用于创立UI界面的根节点,管制UI元素的层级关系和显示成果。11. ScrollSnap(滚动视图疾速定位)介绍:ScrollSnap组件用于在滚动视图中实现疾速定位。用处:罕用于滚动视图中的分页浏览,使用户能够疾速跳转到指定页面。12. GridLayoutGroup(网格布局)介绍:GridLayoutGroup组件用于在UI界面中创立网格布局。用处:罕用于显示多个元素的网格款式布局,例如游戏中的技能面板、背包格子等。13. Mask(遮罩)介绍:Mask组件用于创立遮罩成果。用处:罕用于限度UI元素的可见区域,例如显示部分内容、创立虚构摇杆等。14. ScrollSnapBase(滚动视图根底)介绍:ScrollSnapBase组件是ScrollSnap的根底类。用处:罕用于自定义滚动视图的疾速定位性能。15. RawImage(原始图片)介绍:RawImage组件用于在UI界面上显示原始图片。用处:罕用于显示视频、WebCam等实时图像。16. MaskableGraphic(可遮罩图形)介绍:MaskableGraphic组件是可遮罩图形的根底类。用处:罕用于自定义可遮罩的图形元素,例如实现自定义的遮罩成果。17. LayoutElement(布局元素)介绍:LayoutElement组件用于管制布局元素的大小、地位。用处:罕用于调整UI元素的主动布局形式,例如自适应屏幕大小。18. DropdownOptionData(下拉菜单选项)介绍:DropdownOptionData类用于定义下拉菜单中的选项。用处:罕用于动静生成下拉菜单的选项,例如从数据源中获取选项列表。19. ScrollRectEvent(滚动视图事件)介绍:ScrollRectEvent类用于定义滚动视图的事件。用处:罕用于监听滚动视图的滑动、拖拽等事件,实现自定义的交互逻辑。20. HorizontalLayoutGroup(程度布局)介绍:HorizontalLayoutGroup组件用于创立程度布局。用处:罕用于程度排列多个元素,例如按钮组、菜单栏等。21. VerticalLayoutGroup(垂直布局)介绍:VerticalLayoutGroup组件用于创立垂直布局。用处:罕用于垂直排列多个元素,例如列表、聊天记录等。22. ContentSizeFitter(内容尺寸适应器)介绍:ContentSizeFitter组件用于依据内容主动调整尺寸。用处:罕用于依据内容的大小主动调整UI元素的尺寸,例如文本框、按钮等。23. AspectRatioFitter(宽高比适应器)介绍:AspectRatioFitter组件用于依据宽高比主动调整尺寸。用处:罕用于放弃UI元素的宽高比例不变,适应不同屏幕尺寸。24. CanvasScaler(画布缩放器)介绍:CanvasScaler组件用于调整画布的缩放比例。用处:罕用于适配不同屏幕分辨率,确保UI元素在不同设施上的显示成果统一。之后将会为每个组件的用处及应用形式进行具体解说

July 7, 2023 · 1 min · jiezi

关于c#:Unity的AssetPostprocessor之Model之动画深入解析与实用案例-3

Unity AssetPostprocessor的Model的动画相干的函数批改理论利用在Unity中,AssetPostprocessor是一个十分有用的工具,它能够在导入资源时主动执行一些操作。其中,Model的动画相干的函数批改能够帮忙咱们在导入模型时主动批改动画相干的函数,从而进步咱们的工作效率。本文将介绍如何应用AssetPostprocessor的Model的动画相干的函数批改,并提供多个应用例子。 什么是AssetPostprocessorAssetPostprocessor是Unity中的一个类,它能够在导入资源时主动执行一些操作。咱们能够通过继承AssetPostprocessor并重写其中的办法来实现本人的需要。其中,Model的动画相干的函数批改是AssetPostprocessor中的一个性能,它能够帮忙咱们在导入模型时主动批改动画相干的函数。 Model的动画相干的函数批改在Unity中,咱们能够通过Animator组件来管制模型的动画。Animator组件中蕴含了一些动画相干的函数,例如SetBool、SetFloat、SetInteger等。这些函数能够帮忙咱们管制动画的播放。在导入模型时,咱们能够通过AssetPostprocessor的Model的动画相干的函数批改来主动批改这些函数。 批改SetBool函数咱们能够通过批改SetBool函数来管制动画的播放。例如,咱们能够在导入模型时主动将所有的SetBool函数中的参数名“isRunning”改为“isWalking”,从而管制动画的播放。具体实现如下: using UnityEngine;using UnityEditor;public class ModelPostprocessor : AssetPostprocessor{ void OnPostprocessModel(GameObject go) { Animator animator = go.GetComponent<Animator>(); if (animator != null) { AnimatorController controller = animator.runtimeAnimatorController as AnimatorController; if (controller != null) { foreach (AnimatorControllerParameter parameter in controller.parameters) { if (parameter.type == AnimatorControllerParameterType.Bool) { foreach (AnimationClip clip in controller.animationClips) { AnimationEvent[] events = AnimationUtility.GetAnimationEvents(clip); foreach (AnimationEvent e in events) { if (e.functionName == "SetBool" && e.stringParameter == "isRunning") { e.stringParameter = "isWalking"; AnimationUtility.SetAnimationEvents(clip, events); } } } } } } } }}批改SetFloat函数咱们也能够通过批改SetFloat函数来管制动画的播放。例如,咱们能够在导入模型时主动将所有的SetFloat函数中的参数名“speed”改为“velocity”,从而管制动画的播放。具体实现如下: ...

July 7, 2023 · 3 min · jiezi

关于c#:Unity的AssetPostprocessor之Model深入解析与实用案例-2

Unity AssetPostprocessor中Model相干函数的理论利用Unity AssetPostprocessor是Unity引擎中的一个重要性能,它能够在导入资源时主动一些脚本,以便对资源进行自定义解决。其中,Model相干的函数能够用于对导入的3D模型进行解决,包含批改模型的材质、纹理、网格等属性。本文将介绍Model相干函数的理论利用,并提供多个应用例子。 ModelImporterMaterialNameModelImporterMaterialName函数能够用于批改模型的材质名称。例如,咱们能够将所有模型的材质名称都批改为“DefaultMaterial”。具体实现如下: using UnityEngine;using UnityEditor;public class MyModelPostprocessor : AssetPostprocessor{ void OnPreprocessModel() { ModelImporter importer = assetImporter as ModelImporter; importer.materialName = "DefaultMaterial"; }}ModelImporterMaterialSearchModelImporterMaterialSearch函数能够用于批改模型的材质搜寻门路。例如,咱们能够将所有模型的材质搜寻门路都批改为“Assets/Materials”。具体实现如下: using UnityEngine;using UnityEditor;public class MyModelPostprocessor : AssetPostprocessor{ void OnPreprocessModel() { ModelImporter importer = assetImporter as ModelImporter; importer.materialSearch = ModelImporterMaterialSearch.Local; importer.materialSearchPath = "Assets/Materials"; }}ModelImporterMaterialImportModeModelImporterMaterialImportMode函数能够用于批改模型的材质导入模式。例如,咱们能够将所有模型的材质导入模式都批改为“None”。具体实现如下: using UnityEngine;using UnityEditor;public class MyModelPostprocessor : AssetPostprocessor{ void OnPreprocessModel() { ModelImporter importer = assetImporter as ModelImporter; importer.materialImportMode = ModelImporterMaterialImportMode.None; }}ModelImporterMeshCompressionModelImporterMeshCompression函数能够用于批改模型的网格压缩形式。例如,咱们能够将所有模型的网格压缩形式都批改为“Off”。具体实现如下: using UnityEngine;using UnityEditor;public class MyModelPostprocessor : AssetPostprocessor{ void OnPreprocessModel() { ModelImporter importer = assetImporter as ModelImporter; importer.meshCompression = ModelImporterMeshCompression.Off; }}ModelImporterNormalsModelImporterNormals函数能够用于批改模型的法线计算形式。例如,咱们能够将所有模型的法线计算形式都批改为“Calculate”.具体实现如下: ...

July 6, 2023 · 1 min · jiezi

关于c#:CVBNET快速而简单的免费SVG到PDF转换技巧

在日常工作中,咱们经常须要将SVG转换为PDF格局。这是因为SVG格局的图像在打印时可能会呈现问题,例如失去分辨率或无奈正确适应纸张大小。与此相比,PDF格局则专门用于打印和共享文档,能够确保高质量输入,并且可能主动适应不同的纸张大小。在本文中,咱们将介绍如何应用编程形式将SVG文件转换为PDF,并以C#代码示例演示该过程。一起学起来吧! 1. 筹备工作办法1:将Free Spire.PDF for .NET 下载到本地,解压,找到 BIN 文件夹下的 Spire.PDF.dll。而后在 Visual Studio 中关上“解决方案资源管理器”,鼠标右键点击“援用”,“增加援用”,将本地门路 BIN 文件夹下的 dll 文件增加援用至程序。办法2::通过NuGet装置。可通过以下 2 种办法装置: 能够在 Visual Studio 中关上“解决方案资源管理器”,鼠标右键点击“援用”,“治理 NuGet 包”,而后搜寻“Free Spire.PDF”,点击“装置”。期待程序安装实现。将以下内容复制到 PM 控制台装置。Install-Package FreeSpire.PDF -Version 8.6.0 具体步骤依照下列操作,仅需三步即可实现对SVG文件的转换。 创立PdfDocument对象。应用PdfDocument.LoadFromFile() 办法加载一个示例SVG文件。应用PdfDocument.SaveToFile(String, FileFormat) 办法将SVG文件转换为PDF。 残缺代码C# using Spire.Pdf;namespace SVGtoPDF{ class Program { static void Main(string[] args) { //创立PdfDocument对象 PdfDocument doc = new PdfDocument(); //加载一个示例SVG文件 doc.LoadFromSvg("Sample.svg"); //保留后果文档 doc.SaveToFile("Result.pdf", FileFormat.PDF); doc.Dispose(); } }}VB.NET Imports Spire.PdfNamespace SVGtoPDF Friend Class Program Private Shared Sub Main(ByVal args As String()) '创立PdfDocument对象 Dim doc As PdfDocument = New PdfDocument() '加载一个示例SVG文件 doc.LoadFromSvg("Sample.svg") '保留后果文档 doc.SaveToFile("Result.pdf", FileFormat.PDF) doc.Dispose() End Sub End ClassEnd Namespace效果图 ...

June 16, 2023 · 1 min · jiezi

关于c#:Unity的AssetPostprocessor之Model深入解析与实用案例-1

Unity AssetPostprocessor模型相干函数详解在Unity中,AssetPostprocessor是一个十分有用的工具,它能够在导入资源时主动执行一些操作。在本文中,咱们将重点介绍AssetPostprocessor中与模型相干的函数,并提供多个应用例子。 OnPostprocessModelOnPostprocessModel是AssetPostprocessor中与模型相干的次要函数。它在导入模型时主动调用,并容许咱们对模型进行一些自定义操作。上面是一个简略的例子: using UnityEngine;using UnityEditor;public class MyModelPostprocessor : AssetPostprocessor{ void OnPostprocessModel(GameObject model) { // 在这里对模型进行自定义操作 }}在这个例子中,咱们创立了名为MyModelPostprocessor的AssetPostprocessor类,并重写了OnPostprocessModel函数。在这个函数中,咱们能够对导入的模型进行自定义操作。 上面是一些常见的用: 1. 批改模型的材质void OnPostprocessModel(GameObject model){ Renderer[] renderers = model.GetComponentsInChildren<Renderer>(); foreach (Renderer renderer in renderers) { Material[] materials = renderer.sharedMaterials; for (int i = 0; i < materials.Length; i++) { // 批改材质 materials[i] = new Material(Shader.Find("Standard")); } renderer.sharedMaterials = materials; }}在这个例子中,咱们获取了模型中所有的Renderer组件,并遍历每个Renderer的材质。而后,咱们将每个材质替换为一个新的Standard材质。 2. 批改模型的网格void OnPostprocessModel(GameObject model){ MeshFilter[] meshFilters = model.GetComponentsInChildren<MeshFilter>(); foreach (MeshFilter meshFilter in meshFilters) { // 批改网格 Mesh mesh = meshFilter.sharedMesh; Vector3[] vertices = mesh.vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i] += Vector3.up; } mesh.vertices = vertices; mesh.RecalculateNormals(); }}在这个例子中,咱们获取了模型中所有的MeshFilter组件,并遍历每个MeshFilter的网格。而后,咱们将每个网格的顶点向上挪动一个单位。 ...

May 29, 2023 · 3 min · jiezi

关于c#:CVBNET如何从-PowerPoint-演示文稿中提取文本

在学习或者日常工作中,有时咱们须要把幻灯片的货色整顿成文字,而从 PowerPoint 演示文稿中一张一张的整顿手动复制粘贴,整个过程会十分费精力且耗时。那么怎么样能力比拟轻松且疾速地提取PowerPoint中的文字呢?明天这篇文章就将为你介绍如何通过编程形式提取PowerPoint中的文字,文章最初附有C#/VB.NET代码以及效果图,心愿对你有所帮忙。 程序环境本次测试时,在程序中引入Free Spire.Presentation for .NET。可通过以下办法援用 Free Spire.Presentation.dll文件:办法1:将 Free Spire.Presentation for .NET下载到本地,解压,装置。装置实现后,找到装置门路下BIN文件夹中的 Spire.Presentation.dll。而后在Visual Studio中关上“解决方案资源管理器”,鼠标右键点击“援用”,“增加援用”,将本地门路BIN文件夹下的dll文件增加援用至程序。办法2:通过NuGet装置。可通过以下2种办法装置:(1)能够在Visual Studio中关上“解决方案资源管理器”,鼠标右键点击“援用”,“治理NuGet包”,而后搜寻“Free Spire.Presentation”,点击“装置”。期待程序安装实现。(2)将以下内容复制到PM控制台装置。Install-Package FreeSpire.Presentation -Version 7.8.0 从 PowerPoint 演示文稿中提取文本为了便于在 PowerPoint 文档中共享或传递文本信息,有时须要进行文本提取操作。以下是从所有演示文稿幻灯片中提取文本并保留在 TXT 文件中的步骤。 初始化 Presentation 类的实例。应用 Presentation.LoadFromFile() 办法加载 PowerPoint 文档示例。创立 StringBuilder 实例。遍历文档中的每张幻灯片,而后遍历每张幻灯片中的所有形态。确定形态是否为 IAutoShape 类型。如果是,则遍历每个形态中的所有段落,并应用 TextParagraph.Text 属性获取段落文本。应用 StringBuilder.AppendLine() 办法将提取的文本附加到StringBuilder实例创立一个新的txt文件,并应用 File.WriteAllText() 办法将提取的文本写入该文件。 残缺代码C# using Spire.Presentation;using Spire.Presentation.Charts;using Spire.Presentation.Converter.Equation.Word;using System;using System.IO;using System.Text;namespace ExtractText{ class Program { static void Main(string[] args) { //初始化Presentation类的实例 Presentation presentation = new Presentation(); //载PowerPoint文档示例 presentation.LoadFromFile("空中楼阁是如何造成的?.pptx"); //创立StringBuilder实例 StringBuilder sb = new StringBuilder(); //遍历文档中的每张幻灯片 foreach (ISlide slide in presentation.Slides) { //遍历每张幻灯片中的每个形态 foreach (IShape shape in slide.Shapes) { //查看形态是否为IAutoShape类型 if (shape is IAutoShape) { //以每种形态遍历所有段落 foreach (TextParagraph tp in (shape as IAutoShape).TextFrame.Paragraphs) { //提取文本并保留到StringBuilder实例 sb.AppendLine(tp.Text); } } } } //创立一个新的txt文件以保留提取的文本 File.WriteAllText("提取文本.txt", sb.ToString()); presentation.Dispose(); } }}VB.NET ...

May 29, 2023 · 1 min · jiezi

关于c#:Unity的Console的控制类LogEntries深入解析与实用案例

应用Unity Console窗口的LogEntries公有类实现自定义日志零碎在Unity开发过程中,咱们常常须要应用Console窗口来查看程序运行时的日志信息。Unity内置的日志零碎提供了根本的日志性能,但有时咱们须要更多的自定义选项。本文将介绍如何应用Unity Console窗口的LogEntries公有类来实现自定义日志零碎,并提供多个应用例子。 1. 获取LogEntries公有类的援用首先,咱们须要获取LogEntries公有类的援用。因为LogEntries是一个公有类,咱们须要应用反射来获取它。以下是获取LogEntries类援用的代码: using System;using System.Reflection;using UnityEditor;public class CustomLogSystem{ private static Type logEntriesType; static CustomLogSystem() { Assembly unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow)); logEntriesType = unityEditorAssembly.GetType("UnityEditor.LogEntries"); }}2. 应用LogEntries实现自定义日志性能2.1 清空Console窗口有时咱们心愿在程序运行时主动清空Console窗口,以便查看新的日志信息。咱们能够应用LogEntries.Clear()办法来实现这个性能。以下是清空Console窗口的代码: public static void ClearConsole(){ MethodInfo clearMethod = logEntriesType.GetMethod("Clear", BindingFlags.Static | BindingFlags.Public); clearMethod.Invoke(null, null);}2.2 获取日志数量咱们能够应用LogEntries.GetCount()办法来获取Console窗口中的日志数量。以下是获取日志数量的代码: public static int GetLogCount(){ MethodInfo getCountMethod = logEntriesType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public); return (int)getCountMethod.Invoke(null, null);}2.3 获取特定类型的日志数量有时咱们须要获取特定类型(如谬误、正告、一般日志)的日志数量。咱们能够应用LogEntries.GetCountsByType()办法来实现这个性能。以下是获取特定类型日志数量的代码: public enum LogType{ Error = 0, Warning = 1, Log = 2}public static int GetLogCountByType(LogType logType){ MethodInfo getCountsByTypeMethod = logEntriesType.GetMethod("GetCountsByType", BindingFlags.Static | BindingFlags.Public); int[] counts = new int[3]; getCountsByTypeMethod.Invoke(null, new object[] { counts }); return counts[(int)logType];}3. 应用例子3.1 主动清空Console窗口在程序开始运行时,咱们能够主动清空Console窗口,以便查看新的日志信息。以下是实现主动清空Console窗口的代码: ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的Undo详解解析与实用案例

Unity Undo详解在Unity中,Undo是一个十分重要的性能,它能够让开发者在编辑器中进行操作时,随时撤销之前的操作,从而防止不必要的谬误。本文将具体介绍Unity Undo实现原理和应用办法,并提供多个应用例子,帮忙开发者更好地了解和利用该性能。 实现原理Unity Undo的实现原理是通过记录每个操作的状态,并将其存储在一个Undo栈中。当须要撤销操作时,Unity会从Undo栈中取出最近的操作状态,并将其还原到之前的状态。当须要重做操作时,Unity会从Redo栈中取出最近的操作状态,并将其还原到之后的状态。应用办法Unity Undo的应用办法非常简单,只须要在须要进行Undo的前,调用Undo.RecordObject办法即可。该办法承受两个参数,第一个参数是须要进行Undo的对象,第二个参数是一个形容该操作的字符串。例如: using UnityEngine;public class MyScript : MonoBehaviour{ public int myValue void Update() { Undo.RecordObject(this, "Change My Value"); myValue = Mathf.RoundToInt(Time.time); }}在下面的例子中,咱们在Update办法中调用了Undo.RecordObject办法,将以后对象和一个形容字符串传递给该办法。当咱们在编辑器中批改myValue的值时,Unity会自动记录该操作,并将其存储在栈中。当咱们须要撤销该操作时,只须要按下Ctrl+Z即可。 应用例子例子1:批改Transform组件在Unity中,Transform组件是一个十分罕用的组件,它用于管制游戏对象的地位、旋转和缩放。咱们能够应用Undo性能来撤销对Transform组件的批改。例如: public class MyScript : MonoBehaviour{ void Update() { Undo.RecordObject(transform, "Change Transform"); transform.position = new Vector3(1, 2, 3); transform.rotation = Quaternion.Euler(0, 90, 0); transform.localScale = new Vector3(2, 2, 2); }}在下面的例子中,咱们在Update办法中调用了Undo.RecordObject`办法,并将Transform组件和一个形容字符串传递给该办法。当咱们在编辑器中批改Transform组件的值时,Unity会自动记录该操作,并将其存储在Undo栈中。当咱们须要撤销该操作时,只须要按下Ctrl+Z即可。 例子2:批改数组元素在Unity中,数组是一个十分罕用的数据结构,咱们能够应用Undo性能来撤销对数组元素的批改。例如: using UnityEngine;public class MyScript : MonoBehaviour{ public int[] myArray = new int[3]; void Update() { Undo.RecordObject(this, "Change Array"); myArray[0] = 1; myArray[1] = 2; myArray[2] = 3; }}在下面的例子中,咱们在Update办法中调用了Undo.RecordObject办法,并将以后对象和一个形容字符串传递给该办法。当咱们在编辑器中批改myArray的值时,Unity会自动记录该操作,并将其存储在Undo栈中。当咱们撤销该操作时,只须要按下Ctrl+Z即可。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的UnityStats-属性详解与实用案例

UnityStats 属性详解UnityStats 是 Unity 引擎提供的一个用于监测游戏性能的工具,它提供了一系列的属性值,能够帮忙开发者解游戏的运行状况,从而进行优化。本文将具体介绍 UnityStats 的每个属性值,并提供多个应用例子帮忙开发者更好地应用 UnityStats。 帧率相干属性UnityStats.fpsUnityStats.fps 属性用于获取以后游戏的帧率。它返回一个浮点数,示意以后游戏的帧率。例如: void Update(){ float fps = UnityStats.fps; Debug.Log("以后帧率:" + fps);}UnityStats.batchedDrawCallsUnityStats.batchedDrawCalls 属性用于获取以后游戏中批处理的绘制调用次数。它返回一个整数,示意以后游戏中批处理的绘制调用次数。例如: void Update(){ int batchedDrawCalls = UnityStats.batchedDrawCalls; Debug.Log("批处理的绘制调用次数:" + batchedDrawCalls);}UnityStats.drawCallsUnityStats.drawCalls 属性用于获取以后游戏中绘制调用次数。它返回一个整数,示意以后游戏中的绘制调用次数。例如: void Update(){ int drawCalls = UnityStats.drawCalls; Debug.Log("绘制调用次数:" + draw);}UnityStats.trianglesUnityStats.triangles 属性用于获取以后游戏中的三角形数量。它返回一个整数,示意以后游戏中的三角形数量。例如: Update(){ int triangles = UnityStats.triangles; Debug.Log("三角形数量:" + triangles);}内存相干属性UnityStats.usedTextureMemorySizeUnityStats.usedTextureMemorySize 属性用于获取以后游戏中应用的纹理内存大小。它返回一个整数,示意以后游戏中应用的纹理内存大小。例如: void Update(){ int usedTextureMemorySize = UnityStats.usedTextureMemorySize; Debug.Log("应用的纹理内存大小:" + usedTextureMemorySize);}UnityStats.usedHeapSizeUnityStats.usedHeapSize 属性用于获取以后游戏中应用的堆内存大小。它返回一个整数,示意以后游戏中应用的堆内存大小。例如: void(){ int usedHeapSize = UnityStats.usedHeapSize; Debug.Log("应用的堆内存大小:" + usedHeapSize);}UnityStats.usedGraphicsMemorySizeUnityStats.usedGraphicsMemorySize 属性用于获取以后游戏中应用的显存大小。它返回一个整数,示意以后游戏中应用的显存大小。例如: ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPostGenerateGradleAndroidProject深入解析与实用案例

Unity IPostGenerateGradleAndroidProjectUnity是一款风行的跨平台游戏引擎,它反对多种平台,包含Android。在Unity中,咱们能够应用IPostGenerateGradleAndroidProject接口来自定义Gradle构建过程。本文将介绍如何应用IPostGenerateGradleAndroidProject接口,并提供三个应用例子。 IPostGenerateGradleAndroidProject接口IPostGenerateGradleAndroidProject接口是Unity提供的一个接口,它容许咱们在Gradle构建过程中执行自定义操作。咱们能够应用它批改Gradle构建文件,增加Gradle插件,或者执行其余自定义操作。 IPostGenerateGradleAndroidProject接口有一个办法:OnPostGenerateGradleAndroidProject。这个办法会在Gradle构建过程中被调用,咱们能够在这个办法中执行自定义操作。 应用例子例子1:批改Gradle构建文件咱们能够应用IPostGenerateGradleAndroidProject接口来批改Gradle构建文件。例如,咱们能够增加一个自定义的Gradle工作来执行一些额定的操作。 using UnityEditor.Android;public class MyPostGenerateGradle : IPostGenerateGradleAndroidProject{ public void OnPostGenerateGradleAndroidProject(string basePath) { string gradlePath = basePath + "/build.gradle"; string gradleContent = File.ReadAllText(gradlePath); gradleContent += "\n" + "task myTask {\n" + " doLast {\n" + " println 'Hello from myTask'\n" + " }\n" + "}\n"; File.WriteAllText(gradlePath, gradleContent); }}在这个例子中,咱们增加了一个名为myTask的Gradle工作,它会在构建过程中执行。这个工作会输入一条音讯,通知咱们它曾经被执行了。 例子2:增加Gradle插件咱们也能够应用IPostGenerateGradleAndroidProject接口来增加Gradle插件。例如,咱们能够增加一个自定义的Gradle插件来执行一些额定的操作。 using UnityEditor.Android;public class MyPostGenerateGradle : IPostGenerateGradleAndroidProject{ public void OnPostGenerateGradleAndroidProject(string basePath) { string gradlePath = basePath + "/build.gradle"; string gradleContent = File.ReadAllText(gradlePath); gradleContent += "\n" + "buildscript {\n" + " repositories {\n" + " mavenCentral()\n" + " }\n" + " dependencies {\n" + " classpath 'com.example:my-plugin:1.0'\n" + " }\n" + "}\n" + "apply plugin: 'com.example.my-plugin'\n"; File.WriteAllText(gradlePath, gradleContent); }}在这个例子中,咱们增加了一个名为com.example.my-plugin的Gradle插件,它会在构建过程中执行这个插件会执行一些额定的操作,例如生成一些额定的文件或者执行一些额定的工作。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IUnityLinkerProcessor深入解析与实用案例

Unity IUnityLinkerProcessorUnity IUnityLinkerProcessor是Unity引擎中的一个接口,它容许开发者在Unity我的项目构建时对代码进行链接解决。这个接口能够用来优化我的项目构建大小,缩小不必要的代码和资源,进步我的项目的性能和加载速度。 接口定义IUnityLinkerProcessor接口定义如下: namespace UnityEditor.Build.IPA{ public interface IUnityLinkerProcessor { void OnBeforeRun(LinkXml linkXml); void OnProcessAssembly(string inputFile, string[] searchDirs, string outputFile); }}其中,OnBeforeRun办法在Unity构建我的项目之前被调用,能够用来解决Link.xml文件。OnProcessAssembly办法在Unity构建我的项目时被调用,能够用来解决每个输出程序集。 Link.xml文件Link.xml文件是Unity我的项目中的一个XML文件,用于指定须要保留的程序集、类型和成员。Link.xml文件的格局如下: <linker> <assembly fullname="AssemblyName"> <type fullname="TypeName" preserve="method" /> </assembly></linker>其中,assembly元素指定须要保留的程序集,fullname属性指定程序集的残缺名称。type元素指定须要保留的类型,fullname属性指定类型的残缺名称,preserve属性指定须要保留的成员类型,能够是method、field、property、event等。 应用例子上面给出三个应用例子,别离演示如何应用IUnityLinkerProcessor接口来优化Unity我的项目的构建大小。 例子1:保留指定程序集在Link.xml文件中指定须要保留的程序集,其余程序集将被删除。 <linker> <assembly fullname="Assembly-CSharp" /></linker>在IUnityLinkerProcessor接口的OnBeforeRun办法中读取Link.xml文件,将须要保留的程序集增加到LinkerOptions中。 public void OnBeforeRun(LinkXml linkXml){ foreach (var assembly in linkXml.Assemblies) { if (assembly.Fullname == "Assembly-CSharp") { LinkerOptions.LinkAssemblies.Add(assembly.Fullname); } }}例子2:保留指定类型和成员在Link.xml文件中指定须要保留的类型和成员,其余类型和成员将被删除。 <linker> <assembly fullname="Assembly-CSharp"> <type fullnameMyClass"> <method signature="System.Void MyMethod()" /> </type> </assembly></linker>在IUnityLinkerProcessor接口的OnBeforeRun办法中读取Link.xml文件,须要保留的类型和成员增加到LinkerOptions中。 public void OnBeforeRun(LinkXml linkXml){ foreach (var assembly in linkXml.Assemblies) { if (assembly.Fullname == "Assembly-CSharp") { foreach (var type in assembly.Types) { if (type.Fullname == "MyClass") { foreach (var method in type.Methods) { if (method.Signature == "System.Void MyMethod()") { LinkerOptions.LinkType(type.Fullname); LinkerOptions.LinkMethod(method.Signature); } } } } } }}例子3:删除指定程序集在Link.xml文件中指定须要删除的程序集,其余程序集将被保留。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IGenerateNativePluginsForAssemblies深入解析与实用案例

Unity IGenerateNativePluginsForAssembliesUnity是一款十分风行的游戏引擎,它反对多种平台,包含Windows、Mac、Linux、Android、iOS等。在Unity中,咱们能够应用C#编写游逻辑,然而有些时候咱们须要应用一些原生的代码来实现一些高性能的性能,比方图像处理、音频等。这时候,咱们就须要应用Unity的IGenerateNativePluginsForAssemblies性能来生成原生插件。 什么是IGenerateNativePluginsForAssembliesIGenerateNativePluginsForAssemblies是Unity的一个性能,它能够将C#代码编译成原生代码,并生成一个动态链接库(DLL)。这个DLL能够被Unity加载,并且能够在C#代码中调用其中的函数。这样,咱们就能够应用原生代码来实现一些高性能的性能。 如何应用IGeneratePluginsForAssemblies应用IGenerateNativePluginsForAssemblies非常简单,只须要依照以下步骤即可: 在Unity中创立一个C#类,并在其中定义须要编译成原生代码的函数。在Unity的菜单栏中抉择Assets -> Generate Code,而后抉择须要编译的C#类。Unity会主动编译C#代码,并生成一个DLL文件。例子1:应用IGenerateNativePluginsForAssemblies实现图像处理上面是一个应用IGenerateNativePluginsForAssemblies实现图像处理的例子。咱们须要应用OpenCV库来实现图像处理,此须要先装置OpenCV库。 using UnityEngine;using System.Runtime.InteropServices;public class ImageProcessor{ [DllImport("ImageProcessor")] private static extern void ProcessImage(byte[] data, int width, int height); public static void Process(Texture2D texture) { byte[] data = texture.GetRawTextureData(); ProcessImage(data, texture.width, texture.height); }}在下面的代码中,咱们定义了一个名为ImageProcessor的类,并在其中定义了一个名为Process的动态函数。这函数承受一个Texture2D对象作为参数,并将其转换为一个字节数组。而后,它调用了一个名为ProcessImage的原生函数,这个函数应用OpenCV库来解决图像。 为了让Unity可能调用这个原生函数咱们须要在函数后面加上DllImport属性,并指定原生函数的名称和DLL文件的名称。在这个例子中,原生函数的名称为Image,DLL文件的名称为ImageProcessor。 例子2:应用IGenerateNativePluginsForAssemblies实现音频解决上面是一个应用IGenerateNativePluginsForAssemblies实现音频解决的例子。咱们须要应用FMOD库来实现音频解决,因而须要先安FMOD库。 using UnityEngine;using System.Runtime.InteropServices;public class AudioProcessor{ [DllImport("AudioProcessor")] private static extern void ProcessAudio(float[] data, int length); public static void Process(AudioClip clip) { float[] data = new float[clip.samples * clip.channels]; clip.GetData(data, 0); ProcessAudio(data, data.Length); }}在下面的代码中,咱们定义了一个名为AudioProcessor的类,并在其中定义了一个名为Process的动态函数。这个函数承受一个AudioClip对象作为参数,并将其转换为一个浮点数数组。而后,它调用了一个名为ProcessAudio的原生函数,这个应用FMOD库来解决音频。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPreprocessComputeShaders深入解析与实用案例

Unity IPreprocessComputeShadersUnity IPreprocessComputeShaders是Unity引擎中的一个十分有用的性能,它能够让开发者编译Compute Shader时自定义哪些操作须要被执行。这个能够帮忙开发者更好地管制Compute Shader的编译过程,确保在编译Compute Shader时执行必要的操作。在本文中,咱们介绍Unity IPreprocessComputeShaders的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPreprocessComputeShaders的应用办法Unity IPreprocessComputeShaders是一个接口,它在编译Compute Shader时被调用。在这个接口中,咱们能够编写咱们须要执行的操作,并且能够获取以后的Compute Shader。下是一个简略的例子,演示了如何在编Compute Shader时执行一些操作: using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ComputeShaderPreprocessor : IPreprocessComputeShaders{ public int callbackOrder { get { return 0; } } public void OnProcessComputeShader(ComputeShader shader) { // Do something with the compute shader }}在这个例子中,咱们实现了IPreprocessComputeShaders接口,并重写了它的OnProcessComputeShader办法。在这个办法中,咱们能够获取以后的Compute Shader,并执行咱们须要执行的操作。 应用例子上面是三个应用Unity IPreprocessComputeShaders的例子,每个例子都供了具体的实现。 例子1:批改Compute Shader的属性在这个例子中,咱们将演示如何批改Compute Shader的属性。 using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ComputeShaderPreprocessor : IPreprocessComputeShaders{ public int callbackOrder { get { return 0; } } public void OnProcessComputeShader(ComputeShader shader) { shader.SetInt("MY_DEFINE", 1); shader.SetTexture(0, "MY_TEXTURE", myTexture); }}在这个例子中,咱们实现了IPreprocessComputeShaders接口,并重写了它的OnProcessComputeShader办法。在这个办法中,咱们首先应用Compute Shader的SetInt办法设置了一个整型变量,而后应用SetTexture办法设置了一个纹理变量。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPreprocessShaders深入解析与实用案例

Unity IPreprocessShadersUnity IPreprocessShaders是Unity引擎中的一个十分有用的性能,它能够让开发者在编译Shader时自定义哪些操作须要被执行。这个能够帮忙开发者更好地管制Shader的编译过程,确保在编译Shader时执行必要的操作。在本文中,咱们介绍Unity IPreprocessShaders的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPreprocessShaders的应用办法Unity IPreprocessShaders是一个接口,它在编译Shader时被调用。在这个口中,咱们能够编写咱们须要执行的操作,并且能够获取以后的Shader。下是一个简略的例子,演示了如何在编译Shader时执行一些操作: using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ShaderPreprocessor : IPreprocessShaders{ public int callbackOrder { get { return 0; } } public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData) { // Do something with the shader }}在这个例子中,咱们实现了IPreprocessShaders接口,并重写了它的OnProcessShader办法。在这个办法中,咱们能够获取以后的Shader,并执行咱们须要执行的操作。 应用例子上面是三个应用Unity IPreprocessShaders的例子,每个例子都供了具体的现。 例子1:批改Shader的属性在这个例子中,咱们将演示如何批改Shader的属性。 using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ShaderPreprocessor : IPreprocessShaders{ public int callbackOrder { get { return 0; } } public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData) { if (snippet.passType == PassType.ForwardBase) { foreach (var data in shaderCompilerData) { data.shaderCompilerOptions.Add("d3d11_no_compute_shaders", "true"); } } }}在这个例子中,咱们实现了IPreprocessShaders接口,并重写了它的OnProcessShader办法。在这个办法中,咱们首先判断以后的Shader是否是ForwardBase类型的。而后,咱们遍历所有的ShaderCompilerData,并向它们的shaderCompilerOptions中增加一个选项。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IActiveBuildTargetChanged深入解析与实用案例

Unity IActiveBuildTargetChangedUnity IActiveBuildTargetChanged是Unity引擎中的一个十分有用的性能,它能够让开发者在切换构建平台时自定义哪些操作须要被执行。这个性能能够帮忙开发者更好地管制我的项目的构建过程,确保在切换构建平台时执行必要的操作。在本文中,咱们将介绍Unity IActiveBuildTargetChanged的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IActiveBuildTargetChanged的应用办法Unity IActiveBuildTargetChanged是一个事件,它在切换构建平台时被触发。在这个事件中,咱们能够编写咱们须要执行的操作,并且能够获取以后的构建平台。下是一个简略的例子,演示了如何在切换构建平台时执行一些操作: using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class BuildHandler : IActiveBuildTargetChanged{ public int callbackOrder { get { return 0; } } public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget) { if (newTarget == BuildTarget.Android) { // Do something for Android build target } else if (newTarget == BuildTarget.iOS) { // Do something for iOS build target } else { // Do something for other build targets } }}在这个例子中,咱们实现了IActiveBuildTargetChanged接口,并重写了它的OnActiveBuildTargetChanged办法。在这个办法中,咱们首先获取以后的构建平台。而后,咱们依据以后的构建平台执行相应的操作。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPostBuildPlayerScriptDLLs深入解析与实用案例

Unity IPostBuildPlayerScriptDLLsUnity IPostBuildPlayerScriptDLLs是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目后自定义哪些文件须要被复制到输入目录中。这个性能能够帮忙开发者更好地管制我的项目的构建过程,确保输入目录只蕴含必要的DLL文件。在本文中,咱们将介绍Unity IPostBuildPlayerScriptDLLs的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPostBuildPlayerScriptDLLs的应用办法Unity IPostBuildPlayerScriptDLLs是一个接口,它蕴含一个名为OnPostBuildPlayerScriptDLLs办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目后自定义哪些DLL文件须要被复制到输入目录中: using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEditor.Callbacks;using System.IO;public class BuildHandler : IPostBuildPlayerScriptDLLs{ public int callbackOrder { get { return 0; } } public void OnPostBuildPlayerScriptDLLs(BuildReport report) { string outputDirectory = Path.GetDirectoryName(report.summary.outputPath); string[] dllFiles = Directory.GetFiles(outputDirectory, "*.dll", SearchOption.AllDirectories); foreach (string dllFile in dllFiles) { if (!dllFile.Contains("MyNamespace")) { File.Delete(dllFile); } } }}在这个例子中,咱们实现了IPostBuildPlayerScriptDLLs接口,并重写了它的OnPostBuildPlayerScriptDLLs办法。在这个办法中咱们首先获取输入目录的门路。而后,咱们遍历输入目录中的所有DLL文件,如果DLL文件的名称不蕴含"MyNamespace",则将其删除。 应用例子上面是三个应用Unity IPostBuildPlayerScriptDLLs的例子,每个例子都供了具体的实现。 例子1:只复制指定的DLL文件在这个例子中,咱们将演示如何在构建我的项目后只复制指定的DLL文件。 using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEditor.Callbacks;using System.IO;public class BuildHandler : IPostBuildPlayerScriptDLLs{ public int callbackOrder { get { return 0; } } public void OnPostBuildPlayerScriptDLLs(BuildReport report) { string outputDirectory = Path.GetDirectoryName(report.summary.outputPath); string[] dllFiles = Directory.GetFiles(outputDirectory, "*.dll", SearchOption.AllDirectories); foreach (string dllFile in dllFiles) { if (dllFile.Contains("MyNamespace")) { File.Copy(dllFile, Path.Combine(outputDirectory, Path.GetFileName(dllFile)), true); } } }}在这个例子中,咱们实现了IPostBuildPlayerScriptDLLs接口,并重写了它的OnPostBuildPlayerScriptDLLs办法。在这个办法中,咱们首先获取输入目录的门路。而后,咱们遍历输入目录中的所有DLL文件,如果DLL文件的名称含"MyNamespace",则将其复制到输入目录中。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IFilterBuildAssemblies深入解析与实用案例

Unity IFilterBuildAssembliesUnity IFilterBuildAssemblies是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时自定义哪些程序集须要被蕴含在构建中,哪些程序集须要被排除在建之外。这个性能能够帮忙开发者更好地管制我的项目的构建过程,缩小构建工夫和构建大小。在本文中,咱们将介绍Unity IFilterBuildAssemblies的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IFilterBuildAssemblies的应用办法Unity IFilterBuildAssemblies是一个接口,它蕴含一个名为Filter办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目时自定义哪些程序集须要被蕴含在构建中,哪些程序集须要被排除在构建外: using UnityEditor.Build;using UnityEditor.Build.Reporting;using System.Collections.Generic;public class BuildHandler : IFilterBuildAssemblies{ public int callbackOrder { get { return 0; } } public void OnBeforeBuild() { // Do nothing } public void OnAfterBuild() { // Do nothing } public string[] OnFilterAssemblies(string[] assemblies) { List<string> filteredAssemblies = new List<string>(); foreach (string assembly in assemblies) { if (assembly.Contains("MyNamespace")) { filteredAssemblies.Add(assembly); } } return filteredAssemblies.ToArray(); }}在这个例子中,咱们实现了IFilterBuildAssemblies接口,并重写了它的OnFilterAssemblies办法。在这个办法中,咱们首先创立了一个空的List<string>对象,用于存储须要蕴含在构建中的程序集。而后,咱们遍历所有的程序集,如果程序集的名称蕴含"MyNamespace",则将其增加到List<string>对象中。最初,咱们将List<string>对象转换为string[]数组,并返回这个数组。 应用例子上面是三个应用Unity IFilterBuildAssemblies的例子,每个例子都供了具体的实现。 例子1:只蕴含指定的程序集在这个例子中,咱们将演示如何在构建我的项目时只蕴含指定的程序集。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPostprocessBuildWithReport深入解析与实用案例

Unity IPostprocessBuildWithReportUnity IPostprocessBuildWithReport是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目后主动执行一些操作,并且能够获取构建报告。这个性能能够帮忙开发进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity IPostprocessBuildWithReport的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity IPostprocessBuildWithReport的应用办法Unity IPostprocessBuildWithReport是一个接口,它蕴含一个名为PostprocessBuild办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目后主动关上目录,并获取构建报: using UnityEditor.Build.Reporting;using UnityEngine;using System.Diagnostics;public class BuildHandler : IPostprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; Process.Start(outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPostprocessBuildWithReport接口,并重写了它的OnPostprocessBuild办法。在这个办法中,首先获取构建报告的门路,而后应用Process.Start办法关上这个输入目录。最初,咱们应用Debug.Log办法输入构建报告的后果。 应用例子上面是三个应用Unity IPostprocessBuildWithReport的例子,每个例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目后主动上传构建后果,并获取构报告。 using UnityEditor.Build.Reporting;using UnityEngine;using System.Net;using System.IO;public class BuildHandler : IPostprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPostprocessBuildWithReport接口,并重写了它的OnPostprocessBuild办法。在这个办法中,咱们首先获取构建报告的输入门路,而后指定上传的URL,创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。最初,咱们应用Debug.Log办法输入建报告的后果。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPreprocessBuildWithReport深入解析与实用案例

Unity IPreprocessBuildWithReportUnity IPreprocessBuildWithReport是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时主动执行一些操作,并且能够获取构建报告。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity IPreprocessBuildWithReport的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity IPreprocessBuildWithReport的应用办法Unity IPreprocessBuildWithReport是一个接口,它蕴含一个名为processBuild办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目时主动关上目录,并获取构建报告: using UnityEditor;using UnityEngineusing UnityEditor.Build;using UnityEditor.Build.Reporting;using System.Diagnostics;public class BuildHandler : IPreprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; Process.Start(outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPreprocessBuildWithReport接口,并重写了它的PreprocessBuild办法。在这个办法中,首先获取构建报告的输入门路,而后应用Process.Start办法关上这个输入目录。最初,咱们应用Debug.Log办法输入构建报告的后果。 应用例子上面是三个应用Unity IPreprocessBuildWithReport的例子,每个例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目时主动上传构建后果,并获取构建报告。 using UnityEditor;using UnityEngine;using UnityEditor.Build;using UnityEditor.Build.Reporting;using System.Net;using System.IO;public class BuildHandler : IPreprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPreprocessBuildWithReport接口,并重写了它的PreprocessBuild办法。在这个办法中,咱们首先获取构建报告的输入门路,而后指定上传的URL,创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。最初,咱们应用Debug.Log办法输入构建报告的后果。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的BuildPlayerProcessor深入解析与实用案例

Unity BuildPlayerProcessorUnity BuildPlayerProcessor是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时主动执行一些操作。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity BuildPlayerProcessor的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity BuildPlayerProcessor的应用办法Unity BuildPlayerProcessor是一个动态类,它蕴含一个名为BuildPlayer的静态方法。在这个办法中,咱们能够编写咱们须要执行的操作。下是一个简略的例子,演示了如何在构建我的项目时主动关上目录: using UnityEditor;using UnityEngine;using System.Diagnostics;public class BuildHandler{ [MenuItem("Build/Build and Open Output Folder")] public static void BuildAndOpenOutputFolder() { string outputPath = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "", ""); if (outputPath.Length == 0) return; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = EditorBuildSettings.scenes; buildPlayerOptions.locationPathName = outputPath; buildPlayerOptions.target = BuildTarget.StandaloneWindows64; buildPlayerOptions.options = BuildOptions.None; BuildPipeline.BuildPlayer(buildPlayerOptions); Process.Start(outputPath); }}在这个例子中,咱们首先应用EditorUtility的SaveFolderPanel办法获取构建我的项目的输入门路。而后,咱们创立一个BuildPlayerOptions,并设置它的scenes、locationPathName、target和options属性。接着,咱们调用BuildPipeline的BuildPlayer办法,构建我的项目。最初,咱们应用Process.Start办法关上这个输入目录。 应用例子上面是三个应用Unity BuildPlayerProcessor的例子,每例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目时主动上传构建后果。 using UnityEditor;using UnityEngine;using System.Net;using System.IO;public class BuildHandler{ [MenuItem("Build/Build and Upload")] public static void BuildAndUpload() { string outputPath = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "", ""); if (outputPath.Length == 0) return; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = EditorBuildSettings.scenes; buildPlayerOptions.locationPathName = outputPath; buildPlayerOptions.target = BuildTarget.StandaloneWindows64; buildPlayerOptions.options = BuildOptions.None; BuildPipeline.BuildPlayer(buildPlayerOptions); string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); }}在这个例子中,咱们首先应用EditorUtility的SaveFolderPanel办法获取构建我的项目的输入门路。而后,咱们创立一个BuildPlayerOptions对象,并设置它的scenes、locationPathName、target和options属性。接着,调用BuildPipeline的BuildPlayer办法,构建我的项目。最初,咱们指定上传的URL,创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPostprocessBuild深入解析与实用案例

Unity IPostprocessBuild技术文章Unity IPostprocessBuild是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目后主动执行一些操作。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity IPostprocessBuild的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity IPostprocessBuild的应用办法Unity IPostprocessBuild的应用办法与IPreprocessBuild相似,只须要在Unity我的项目中创立一个Editor文件夹,而后在这个文件夹中创立一个C#脚本,名为BuildHandler.cs。在这个脚本中,咱们须要应用Unity的Editor命名空间,并实现IPostprocessBuild接口。而后,咱们须要重写OnPostprocessBuild办法,这个办法会在构建我的项目后主动执行。在这个中,咱们能够编写咱们须要执行的操作。上面是一个简略的例子,演示了如何在构建我的项目后主动关上目录: using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;using System.Diagnostics;public class BuildHandler : IPostprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; Process.Start(outputPath); }}在这个例子中,咱们实现了IPostprocessBuild接口,并重写了OnPostprocessBuild办法。在这个办法中,咱们首先获取构建我的项目的输入门路,而后应用Process.Start办法关上这个输入目录。 应用例子上面是三个应用Unity IPostprocessBuild的例子,每个例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目后主动上传构建后果。 using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;using System.Net;using System.IO;public class BuildHandler : IPostprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); }}在这个例子中,咱们首先获取构建我的项目的输入门路,而后指定上传的URL。接着,咱们创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPreprocessBuild深入解析与实用案例

Unity IPreprocessBuildUnity IPreprocessBuild是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时主动执行一些操作。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中咱们将介绍Unity IPreprocessBuild的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPreprocessBuild的应用办法Unity IPreprocessBuild的应用办法非常简单,只须要在Unity我的项目中创立一个Editor文件夹,而后在这个文件夹中创立一个C#脚本,命名为BuildHandler.cs。在这个脚本中,咱们须要应用Unity的Editor命名空间,并实现IPreprocessBuild接口。而后,咱们须要重写OnPreprocessBuild办法,这个办法会在构建我的项目时主动执行。在这个办法中,咱们能够编写咱们须要执行的操作上面是一个简略的例子,演示了如何在构建我的项目时主动批改PlayerSettings: using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;public class BuildHandler : IPreprocessBuild, IPostprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { PlayerSettings.companyName = "My Company"; PlayerSettings.productName = "My Product"; } public void OnPostprocessBuild(BuildReport report) { Debug.Log("Build completed successfully!"); }}在这个例子中,咱们实现了IPreprocessBuild和IPostprocessBuild接口,并重写了OnPreprocessBuild和OnPostprocessBuild办法。在OnPreprocessBuild办法中,咱们批改了PlayerSettings的companyName和productName属性。在OnPostprocessBuild办法中,咱们输入了一条日志,示意构建我的项目曾经实现。 应用例子上面是三个应用Unity IPreprocessBuild的例子,每个例子都提供了具体的实现。 例子1:主动批改场景在这个例子中,咱们将演示如何在构建我的项目时主动批改场景。 using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;using UnityEngine.SceneManagement;public class BuildHandler : IPreprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { Scene scene = SceneManager.GetSceneByName("MyScene"); if (scene.IsValid()) { SceneManager.SetActiveScene(scene); GameObject[] objects = scene.GetRootGameObjects(); foreach (GameObject obj in objects) { obj.transform.position = Vector3.zero; } } }}在这个例子中,咱们首先获取指定的场景,而后将这个场景设置为流动场景。接着,咱们获取场景中的所有根GameObject,并将它们的地位设置为Vector3.zero。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的OnOpenAsset深入解析与实用案例

Unity OnOpenAsset在Unity中,OnOpenAsset是一个十分有用的回调函数,它能够在用户双击资源文件时主动关上一个编辑器窗口。这个回调函数能够用于自定义资源编辑,进步工作效率。本文将介绍OnOpenAsset的应用办法,并提供三个应用例子。 OnOpenAsset的应用办法OnAsset是Unity Editor的一个回调函数,它会在用户双击资源文件时被调用。这个回调函数有两个参数:instanceID和lineNumber。instanceID是资源的惟一标识符,lineNumber是资源文件中的行号。咱们能够利用这两个参数来关上资源编辑器。 要应用OnOpenAsset,咱们须要在Editor文件夹下创立一个脚本,并在脚本中实现OnOpenAsset办法。上面是一个简略的例子: using UnityEditor;using UnityEngine;public class MyEditor : Editor{ [UnityEditor.Callbacks.OnOpenAsset] public static bool OnOpenAsset(int instanceID, int lineNumber) { // 获取资源门路 string assetPath = AssetDatabase.GetAssetPath(instanceID); // 判断资源类型 if (assetPath.EndsWith(".txt")) { // 关上文本编辑器 TextAsset asset = AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath); UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(assetPath, lineNumber); return true; } // 返回false示意不解决该资源 return false; }}在这个例子中,咱们判断资源类型是否为txt文件,如果是则关上文本编辑器。咱们能够依据须要自定义资源编辑器。 应用例案例1:关上场景文件using UnityEditor;using UnityEngine;public class SceneOpener : Editor{ [UnityEditor.Callbacks.OnOpenAsset] public static bool OnOpenAsset(int instanceID, int lineNumber) { // 获取资源门路 string assetPath = AssetDatabase.GetAssetPath(instanceID); // 判断资源类型 if (assetPath.EndsWith(".unity")) { // 关上场景文件 EditorSceneManager.OpenScene(assetPath); return true; } // 返回false示意不解决该资源 return false; }}在这个例子中,咱们判断资源类型是否为unity景文件,如果是则关上场景文件。 ...

May 27, 2023 · 1 min · jiezi

关于c#:Unity中的PostProcessBuild深入解析与实用案例

Unity中的PostProcessBuild:深刻解析与实用案例在Unity游戏开发中,咱们常常须要在构建实现后对生成的应用程序进行一些额定的解决。这时,咱们能够应用Unity提供的PostProcessBuild性能。本文将具体介绍Unity中的PostProcessBuild办法,并通过三个实用案例来展现其弱小的性能。 什么是PostProcessBuild?PostProcessBuild是Unity中的一个性能,容许咱们在构建实现后对生成的应用程序进行一些额定的解决。这能够帮忙咱们自动化一些构建后的工作,如批改配置文件、拷贝资源等。 如何应用PostProcessBuild?要应用PostProcessBuild,咱们须要在Unity我的项目的Assets目录下创立一个名为Editor的文件夹,并在其中创立一个C#脚本,用于编写构建后处理逻辑。而后,咱们须要在脚本中定义一个带有PostProcessBuildAttribute个性的静态方法,该办法将在构建实现后主动执行。 上面是一个简略的PostProcessBuild脚本示例: using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;public class MyPostProcessBuild{ [PostProcessBuild] public static void OnPostProcessBuild(BuildTarget target, string path) { // 在这里编写构建后处理逻辑 }}实用案例接下来,咱们将通过三个实用案例来展现PostProcessBuild的性能。 案例1:批改配置文件在这个案例中,咱们将应用PostProcessBuild在构建实现后主动批改应用程序的配置文件。这能够帮忙咱们依据不同的构建指标生成不同的配置。 首先,咱们须要在Editor文件夹下创立一个C#脚本,用于编写构建后处理逻辑。 using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;public class ConfigModifier{ [PostProcessBuild] public static void OnPostProcessBuild(BuildTarget target, string path) { // 在这里编写批改配置文件的逻辑 }}接下来,咱们能够在OnPostProcessBuild办法中编写批改配置文件的逻辑,如依据构建指标批改数据库连贯字符串等。 在这个例子中,咱们依据不同的构建指标应用程序的配置文件。在OnPostProcessBuild办法中,咱们首先获取应用程序的配置文件门路,而后依据不同的构建指标批改配置文件内容。 using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;using System.IO;public ConfigModifier{ [PostProcessBuild] public static void OnPostProcessBuild(BuildTarget target, string path) { // 获取应用程序的配置文件门路 string configPath = Path.Combine(Path.GetDirectoryName(path), "config.txt"); // 依据不同的构建指标批改配置文件 if (target == BuildTarget.StandaloneWindows64) { File.WriteAllText(configPath, "Windows配置"); } else if (target == BuildTarget.iOS) { File.WriteAllText(configPath, "iOS配置"); } else if (target == BuildTarget.Android) { File.WriteAllText(configPath, "Android配置"); } }}案例2:拷贝资源文件首先,咱们须要在Editor文件夹下创立一个C#脚本,用于编写构建后处理逻辑。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity中的RegisterPlugins深入解析与实用案例

Unity中的RegisterPlugins:深刻解析与实用案例在Unity游戏开发中,咱们常常须要应用第三方插件来实现一些特定的性能。为了让这些插件可能在Unity中失常工作,咱们须要对它们进行注册。本文将具体介绍Unity中的RegisterPlugins办法,并通过三个实用案例来展现其弱小的性能。 什么是RegisterPlugins?RegisterPlugins是Unity中的一个办法,用于在我的项目中注册第三方插件。注册插件后,咱们能够在Unity中间接调用这些插件提供的性能,而无需进行额定的配置。 如何应用RegisterPlugins?要应用RegisterPlugins,咱们须要在Unity我的项目中创立一个名为Plugins的文件夹,并将第三方插件的库文件(如.dll、.so、.a等)放入该文件夹。而后,咱们须要在我的项目的Assets目录下创立一个名为Editor的文件夹,并在其中创立一个C#脚本,用于编写插件注册逻辑。 上面是一个简略的RegisterPlugins脚本示例: using UnityEditor;using UnityEngine;public class MyPluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写插件注册逻辑 }}实用案例接下来,咱们将通过三个实用案例来展现RegisterPlugins的性能。 案例1:注册SQLite数据库插件在这个案例中,咱们将应用RegisterPlugins来注册一个名为SQLite的数据库插件。咱们将在Unity我的项目中应用这个插件来实现本地数据库的存储和查问性能。 首先,咱们须要下载SQLite插件的库文件,并将其放入我的项目的Plugins文件夹。而后,咱们须要在Editor文件夹下创立一个C#脚本,用于编写插件注册逻辑。 using UnityEditor;using UnityEngine;public class SQLitePluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写SQLite插件的注册逻辑 }}接下来,咱们能够在我的项目中应用SQLite插件提供的性能,如创立数据库、执行SQL语句等。 案例2:注册Firebase插件在这个案例中,咱们将应用RegisterPlugins来注册一个名为Firebase的插件。咱们将在Unity我的项目中应用这个插件来实现实时数据库、认证和云存储等性能。 首先,咱们须要下载Firebase插件的库文件,并将其放入我的项目的Plugins文件夹。而后,咱们须要在Editor文件夹下创立一个C#脚本,用于编写插件注册逻辑。 using UnityEditor;using UnityEngine;public class FirebasePluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写Firebase插件的注册逻辑 }}接下来,咱们能够在我的项目中应用Firebase插件提供的性能,如实时数据库的读写、用户认证等。 案例3:注册ARCore插件在这个案例中,咱们将应用RegisterPlugins来注册一个名为ARCore的插件。咱们将在Unity我的项目中应用这个插件来实现加强事实(AR)性能。 首先,咱们须要下载ARCore插件的库文件,并将其放入我的项目的Plugins文件夹。而后,咱们须要在Editor文件夹下创立一个C#脚本,用于编写插件注册逻辑。 using UnityEditor;using UnityEngine;public class ARCorePluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写ARCore插件的注册逻辑 }}接下来,咱们能够在我的项目中应用ARCore插件提供的性能,如追踪立体、搁置虚构物体等。 总结通过以上三个实用案例,咱们能够看到RegisterPlugins在Unity游戏开发中的弱小性能。它能够帮忙咱们轻松地集成第三方插件,进步游戏的可玩性和用户体验。心愿本文能对您在Unity游戏开发中的实际提供一些帮忙。 本文由博客一文多发平台 OpenWrite 公布!

May 27, 2023 · 1 min · jiezi

关于c#:Unity中的PostProcessScene深入解析与实用案例

Unity中的PostProcessScene:深刻解析与实用案例在Unity游戏开发中,咱们常常须要对场景进行后处理,以实现更丰盛的视觉效果。Unity提供了一个名为PostProcessScene的性能,能够让咱们在场景加载实现后,对场景进行一系列的解决。本文将具体介绍PostProcessScene的应用办法,并通过三个实用案例来展现其弱小的性能。 什么是PostProcessScene?PostProcessScene是Unity中的一个事件,当场景加载实现后,它会被触发。咱们能够在这个事件中编写自定义的脚本,对场景进行后处理。这些解决能够包含批改场景中的游戏对象、增加或删除组件、调整光照等。 如何应用PostProcessScene?要应用PostProcessScene,咱们须要创立一个脚本,并在其中编写解决逻辑。而后,咱们须要将这个脚本挂载到一个游戏对象上,并在Unity编辑器中将该游戏对象设置为“DontDestroyOnLoad”,以确保它在场景加载时不会被销毁。 上面是一个简略的PostProcessScene脚本示例: using UnityEngine;using UnityEngine.SceneManagement;public class MyPostProcessScene : MonoBehaviour{ private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // 在这里编写场景后处理逻辑 }}实用案例接下来,咱们将通过三个实用案例来展现PostProcessScene的性能。 案例1:主动调整光照强度在这个案例中,咱们将应用PostProcessScene来主动调整场景中的光照强度。咱们将依据场景中的工夫(白天或夜晚)来设置不同的光照强度。 using UnityEngine;using UnityEngine.SceneManagement;public class AutoAdjustLightIntensity : MonoBehaviour{ public Light mainLight; public float dayIntensity = 1.0f; public float nightIntensity = 0.5f; private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (mainLight == null) { mainLight = GameObject.FindWithTag("MainLight").GetComponent<Light>(); } if (IsDaytime()) { mainLight.intensity = dayIntensity; } else { mainLight.intensity = nightIntensity; } } private bool IsDaytime() { // 在这里编写判断是否为白天的逻辑 // 示例:return DateTime.Now.Hour >= 6 && DateTime.Now.Hour <= 18; return true; }}案例2:动静增加组件在这个案例中,咱们将应用PostProcessScene来动静地为场景中的游戏对象增加组件。咱们将为所有带有“Enemy”标签的游戏对象增加一个名为“Health”的组件。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity中的InitializeOnLoad特性深入解析与实践

Unity中的InitializeOnLoad个性:深刻解析与实际在Unity开发过程中,咱们常常须要在编辑器启动时或脚本从新编译后执行一些操作,例如初始化数据、注册事件等。这时,咱们能够应用InitializeOnLoad个性来实现这一需要。本文将具体介绍InitializeOnLoad个性的用法,并通过三个理论案例来展现其利用场景。 1. InitializeOnLoad个性简介InitializeOnLoad是Unity引擎提供的一种个性,用于在编辑器启动时或脚本从新编译后主动执行指定的操作。这种个性非常适合用于在编辑器启动时执行一些初始化操作,以确保我的项目在启动后可能失常运行。 要应用InitializeOnLoad个性,只需在编辑器脚本中为一个动态类增加该个性即可。例如: using UnityEditor;using UnityEngine;[InitializeOnLoad]public static class MyInitializer{ static MyInitializer() { Debug.Log("InitializeOnLoad called."); }}在这个例子中,咱们创立了一个名为MyInitializer的动态类,并为其增加了InitializeOnLoad个性。当编辑器启动时,MyInitializer类的动态构造函数将被主动调用,从而实现主动初始化的性能。 2. 理论案例上面咱们将通过三个理论案例来展现InitializeOnLoad个性的利用场景。 2.1 主动注册事件在某些状况下,咱们须要在编辑器启动时主动注册事件。例如,咱们可能须要在我的项目中监听某个自定义事件,以便在事件触发时执行相应的操作。这时,咱们能够应用InitializeOnLoad个性来实现主动注册。 using UnityEditor;using UnityEngine;[InitializeOnLoad]public static class EventRegistrar{ static EventRegistrar() { Debug.Log("Event registered."); MyCustomEventManager.OnCustomEvent += HandleCustomEvent; } private static void HandleCustomEvent(object sender, CustomEventArgs e) { Debug.Log("Custom event handled."); }}2.2 主动加载配置文件在某些状况下,咱们须要在编辑器启动时主动加载配置文件。例如,咱们可能须要在我的项目中保护一个全局配置文件,以便在运行时疾速读取配置信息。这时,咱们能够应用InitializeOnLoad个性来实现主动加载。 using UnityEditor;using UnityEngine;[InitializeOnLoad]public static class ConfigLoader{ static ConfigLoader() { Debug.Log("Config file loaded."); LoadConfigFile(); } private static void LoadConfigFile() { // Load the config file and parse its content. }}2.3 主动查看资源更新在某些状况下,咱们须要在编辑器启动时主动查看资源更新。例如,咱们可能须要在我的项目中查看近程服务器上的资源更新,以便在有新资源时及时下载并更新本地资源。这时,咱们能够应用InitializeOnLoad个性来实现主动查看。 ...

May 26, 2023 · 1 min · jiezi

关于c#:C开发租房管理系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档]屋宇租赁管理系统是治理房屋出租、发售信息材料而设计的信息管理系统,蕴含有后盾数据库和前台应用程序零碎两大部分,后盾数据库要求数据的一.致性和完整性、安全性,用以贮存单位工程文档资料及相干信息,前台应用程序零碎要求应用程序性能齐备、易于应用和界面敌对等。引言屋宇租赁管理系统是治理房屋出租、发售信息材料而设计的信息管理系统,蕴含有后盾数据库和前台应用程序零碎两大部分,后盾数据库要求数据的一.致性和完整性、安全性,用以贮存单位工程文档资料及相干信息,前台应用程序零碎要求应用程序性能齐备、易于应用和界面敌对等。20世纪以来,社会生产力迅速倒退,科学技术突飞猛进,人们进行信息交换的深度与广度一直减少,信息量急剧增长,传统的信息处理与决策的伎俩已不能适应社会的须要,信息的重要性和信息处理问题的紧迫性空前进步了,面对着日益简单和一直倒退,变动的社会环境,特地是企业间日趋激烈的竞争局势,一个人、一个企业要在古代社会中求生存,求倒退,必须具备足够的信息和强有力的信息收集与解决伎俩。系统分析与设计需要剖析通过对工作的剖析,能够发现运行的零碎要能实现以下的性能:登录治理:实现以正确的员工号、明码和登录人员身份能力登陆零碎的性能,正确登录之后能力进行之后的治理。屋宇信息管理:包含增加新的房屋信息、批改房屋信息、查问房屋信息、删除房屋信息。用户信息管理:包含增加新的用户信息、批改用户信息、查问用户信息、删除用户信息。租赁信息管理:包含查问某个屋宇的租赁情况、增加租赁关系、删除租赁关系。水电费用治理:包含水电费用的查问、增加、批改、删除。财务收支记录:增加公司的财务记录(不容许批改和删除)。免费我的项目设置:设置水费、电费、物业费、宽带费单价及财务余额。管理员信息保护/明码批改:若登陆用户为超级管理员(admin),则能够治理其余员工的信息,否则就只有批改本人明码的权限。

April 29, 2023 · 1 min · jiezi

关于c#:基于C和MYSQL数据库实现的课程自动考试系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 1 问题定义考试作为教学环节中一个必不可少的局部,是掂量教学质量的重要指标,因而保障考试主观、精确、偏心成为永恒的话题,这不仅关系到人才的提拔和教学的品质,而且波及孩子的将来及千家万户的幸福。随着社会对高常识人才日益减少的需要及高考扩招所带来的学生数量越来越多的社会现状,老师和管理人员的工作量将越来越大,考试治理是一项十分繁琐并且容易出错的事件,能够说传统的考试模式曾经不能再适应社会倒退的需要。随着科学技术的倒退,人们迫切希望可能利用这种技术解决这个问题,加重老师和管理人员的工作压力,进步工作效率,使治理更科学化、规范化,同时进步考试的公平性和信息的安全性。 为了不便学生随时能参加考试进行查漏补缺,无效的布局将来学习打算。为了缩小改卷工作人员的工作量。同时缩小批改时的出错率,进步工作效率。次要使用者老师、在校学生以及其余参考人员等。 2 性能需要本零碎反对新用户注册性能。注册信息包含用户名、明码。其中用户名要求:4-16个字符;明码要求:6-16个字符登录分为学生登录与老师登录,输出用户名和明码,在下方选项中抉择学生或老师后登陆试卷智能生成,零碎依据学生抉择科目主动随机从题库整顿出一套该科目残缺的试卷,题目包含选择题,填空题与判断题试卷智能批阅,零碎依据题库中所给定的标准答案与提交答案比照后产生分数显示给学生题库治理,老师登录后可进行各科目减少、删除和查看试题库中题目等操作试卷治理,老师可对该系统生成过的试卷进行查看、及删除问题治理,零碎主动统计学生考试成绩。3 非性能需要在C/S模式下,学生确认提交试卷后,必须在10秒钟之内显示其考试成绩本零碎客户端反对所有windows零碎,但服务器与客户端须在同一设施上运行零碎需易于保护,投入较少工夫就能改善齐备零碎零碎题库中对应各题的答案必须正确无误

April 27, 2023 · 1 min · jiezi

关于c#:基于C开发三层架构图书管理系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 学校图书馆有许多书,如果靠人工的形式来进行治理,那么工作量会十分大。图书的统计和治理会成为让人头疼的问题,读者借阅图书进行注销也会非常的不不便。这时,利用计算机来为咱们进行这些统计治理的工作,能够给咱们的生存带来大大的便当,并且进步工作效率。因为条件无限,只能应用键盘输入书的信息,所以在输出图书的ISBN号时有些麻烦。所以在课设里,采纳了图书编号。在现实生活中,采纳扫描的形式录入ISBN号会更加精确,高效。 一、我的项目背景及意义当今因为信息技术的飞速发展,图书馆作为社会常识信息媒介的性能日益重要,网络环境下的信息资源建设常识仓库的设计,凋谢存取学术交流模式,常识管理系统,智能检索,数字参考征询,数字图书馆畛域成为图书馆零碎的钻研方向。 治理倒退至今,综合倒退的整体趋势已日渐显著。引进新办法,排汇新思维是促成图书馆零碎倒退的必要条件。因而,图书馆零碎的钻研要保持实践与技术相交融,发展跨学科的穿插钻研;要保持实践与实际相结合,而对事实,答复事实所提出的最迫切的问题;要保持根底钻研和利用钻研,前者对后者起指导作用,后者反过来对前者起丰盛和倒退的作用;要正确处理事实、历史、实践三者之间的关系,这是推动管理系统钻研的重要办法。 二、需要剖析2.1 现状剖析以往,人们应用传统的人工形式治理图书馆的日常业务,其操作流程比拟繁琐。在借书时,读者首先将要借的书好借阅证交给工作人员,而后工作人员将每本书的信息卡片好读者的借阅证放在一个小格栏里,最初在借阅证和每本书贴的借阅条上填写借阅信息。在还书时,读者首先将要还的书交给工作人员,而后工作人员依据图书信息找到相应的书卡好借阅证,并填写相应的还书信息。 学校图书馆有许多书,如果靠人工的形式来进行治理,那么工作量会十分大。图书的统计和治理会成为让人头疼的问题,读者借阅图书进行注销也会非常的不不便。这时,利用计算机来为咱们进行这些统计治理的工作,能够给咱们的生存带来大大的便当,并且进步工作效率。因为条件无限,只能应用键盘输入书的信息,所以在输出图书的ISBN号时有些麻烦。所以在课设里,采纳了图书编号。在现实生活中,采纳扫描的形式录入ISBN号会更加精确,高效。 2.2 零碎性能需要图书管理系统是针对图书馆工作人员开发的管理软件,实现对图书信息、用户信息的治理性能。 本零碎次要可能实现以下性能: 图书信息管理(查问、批改、新增、删除) 用户信息管理(查问、批改、新增、删除) 借书操作、还书操作、续借操作、借书记录查看 图书和用户分类管理(查问、批改、新增、删除) 2.3 零碎设计指标零碎中的数据表设计正当、高效、数据冗余少 软件界面敌对、安全性高 易于保护、不便降级 三、零碎可行性剖析3.1 技术可行性图书管理系统的开发环境是Visual Studio 2010、Microsoft SQL Server 2008R2 SP3。零碎是利用C/S的交互方式实现,本零碎具备稳定性、安全性、好看性、先进性。零碎现阶段的倒退过程中,利用现有的人力物力是齐全具备的能力开发进去的,作为阶段性产品,日后的倒退空间大,实现办法逐渐简略容易,所以图书管理系统的技术上是齐全可行的。在以后的限度条件下,该零碎的性能指标能达到。 3.2 经济可行性计算机专业师生团队能够进行日常的系统维护,工作量少,经济收入少。 3.3 操作可行性所有界面具备格调对立,不同栏目的页面文字格调对立,重点突出图书治理平台的特点,零碎页面敌对,操作简略,即便没有计算机根底的老师也很好上手。 四、应用的相干技术4.1 C#C#是微软公司公布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言。并定于在微软职业开发者论坛(PDC)上登台亮相。C#是一种平安的、稳固的、简略的、优雅的,由C和C++衍生进去的面向对象的编程语言。它在继承C和C++弱小性能的同时去掉了一些它们的简单个性(例如没有宏以及不容许多重继承)。C#综合了VB简略的可视化操作和C++的高运行效率,以其弱小的操作能力、优雅的语法格调、翻新的语言个性和便捷的面向组件编程的反对成为.NET开发的首选语言。 4.2 SQL serverSQL Server是由Microsoft开发和推广的关系数据库管理系统(DBMS),它最后是由Microsoft、Sybase和Ashton-Tate三家公司共同开发的,并于1988年推出了第一个OS/2版本。Microsoft SQL Server近年来不断更新版本,1996年,Microsoft 推出了SQL Server 6.5版本;1998年,SQL Server 7.0版本和用户见面;SQL Server 2000是Microsoft公司于2000年推出,目前最新版本是2017年份推出的SQL SERVER 2017。 五、零碎具体设计5.1 总体设计以Microsoft SQL Server 2008R2 sp3、Visual Studio 2010作为开发环境,应用数据库技术以及.net开发技术,从用C#三层架构:体现层(UI(User Interface))、业务逻辑层(BLL(Business Logic Layer))、数据拜访层(DAL(Data Access Layer))再加上实体类库(Model),开发此图书管理系统。

April 23, 2023 · 1 min · jiezi

关于c#:asyncawait-在-C-语言中是如何工作的下

接《async/await 在 C# 语言中是如何工作的?(上)》、《async/await 在 C# 语言中是如何工作的?(中)》,明天咱们持续介绍 SynchronizationContext 和 ConfigureAwait。 ▌SynchronizationContext 和 ConfigureAwait咱们之前在 EAP 模式的上下文中探讨过 SynchronizationContext,并提到它将再次出现。SynchronizationContext 使得调用可重用的辅助函数成为可能,并主动被调度回调用环境认为适合的任何中央。因而,咱们很天然地认为 async/await 能“失常工作”,事实也的确如此。回到后面的按钮单击处理程序: ThreadPool.QueueUserWorkItem(_ =>{ string message = ComputeMessage(); button1.BeginInvoke(() => { button1.Text = message; });});应用 async/await,咱们能够这样写: button1.Text = await Task.Run(() => ComputeMessage());对 ComputeMessage 的调用被转移到线程池中,这个办法执行结束后,执行又转移回与按钮关联的 UI 线程,设置按钮的 Text 属性就是在这个线程中进行的。 与 SynchronizationContext 的集成由 awaiter 实现(为状态机生成的代码对 SynchronizationContext 无所不知),因为当所示意的异步操作实现时,是 awaiter 负责理论调用或将所提供的 continuation 排队。而自定义 awaiter 不须要思考 SynchronizationContext。目前,Task、Task<TResult>、ValueTask、ValueTask<TResult> 的期待器都是 do。这意味着,默认状况下,当你期待一个工作,一个 Task<TResult>,一个 ValueTask,一个 ValueTask<TResult>,甚至 Task. yield() 调用的后果时,awaiter 默认会查找以后的 SynchronizationContext,如果它胜利地取得了一个非默认的同步上下文,最终会将 continuation 排队到该上下文。 ...

April 23, 2023 · 4 min · jiezi

关于c#:asyncawait-在-C-语言中是如何工作的中

接《async/await 在 C# 语言中是如何工作的?(上)》,明天咱们持续介绍 C# 迭代器和 async/await under the covers。 C# 迭代器这个解决方案的伏笔实际上是在 Task 呈现的几年前,即 C# 2.0,过后它减少了对迭代器的反对。 迭代器容许你编写一个办法,而后由编译器用来实现 IEnumerable<T> 和/或 IEnumerator<T>。例如,如果我想创立一个产生斐波那契数列的枚举数,我能够这样写: public static IEnumerable<int> Fib(){ int prev = 0, next = 1; yield return prev; yield return next; while (true) { int sum = prev + next; yield return sum; prev = next; next = sum; }}而后我能够用 foreach 枚举它: foreach (int i in Fib()){ if (i > 100) break; Console.Write($"{i} ");}我能够通过像 System.Linq.Enumerable 上的组合器将它与其余 IEnumerable<T> 进行组合: ...

April 11, 2023 · 9 min · jiezi

关于c#:使用nssm将net-core的woker-service-注册为windows服务

应用 NSSM (Non-Sucking Service Manager) 能够将 .NET Core Worker Service 注册成 Windows 服务。请依照以下步骤操作: 下载 NSSM:首先,从官方网站下载 NSSM: https://nssm.cc/download。依据您的零碎是 32 位还是 64 位,抉择适合的版本。解压 NSSM:解压下载的 NSSM 压缩包,并将解压后的 nssm.exe 文件挪动到一个适当的文件夹,例如 C:\NSSM\。增加 NSSM 的文件夹门路到环境变量:将 NSSM 的门路增加到零碎环境变量的 Path 中。这能够让您在命令提示符中间接调用 nssm 命令。构建 .NET Core Worker Service:确保您的 .NET Core Worker Service 利用曾经构建并公布,例如,将其公布到 C:\MyWorkerService\ 文件夹下。应用 NSSM 注册 .NET Core Worker Service:要应用 NSSM 注册 Worker Service,请关上一个管理员权限的命令提示符,而后执行以下命令(这只是一个示例,请依据理论状况批改门路): nssm install MyWorkerService "C:\Program Files\dotnet\dotnet.exe" "C:\MyWorkerService\MyWorkerService.dll"在此命令中,MyWorkerService 是您为 Windows 服务设置的名称。请确保应用正确的 .NET Core 运行时门路和 Worker Service 应用程序 DLL 的门路。 ...

April 10, 2023 · 1 min · jiezi

关于c#:盘点-C-80-中好用的特性

减少援用类型可为null://如果参数t是null,则会收回正告public static void Test<T?>(T t){ }模式匹配1、swith 多条件匹配 ## 1 元组模式 int a = 1;int b = 10; string c = (a, b) switch { (1, 10) => "123", _ => "default",};### 应用弃元模式_ = (a, b) switch { (1, 10) => "123", _ => "default",};## 2 地位模式 public class PointA { public int X { get; } public int Y { get; } public int Z { get; } public PointA(int x, int y) => (X, Y) = (x, y); public PointA(int x, int y,int z) => (X, Y,Z) = (x, y,z); public void Deconstruct(out int x, out int y) => (x, y) = (X, Y); public void Deconstruct(out int x, out int y,out int z) => (x, y,z) = (X, Y,Z); }static string GetLocation(PointA point) => point switch { (0, 0) => "1", (0, 0, 0) => "1", var (x, y) when x > 0 && y > 0 =>"2", var (_, _) => "3",// 当 x 或 y 不为null时 _ => "4" };Using 申明## 先相熟下应用 此处 C#7就能用了using static System.Math;using Tasks = System.Threading.Tasks;using (FileStream fileStream = new FileStream("", FileMode.Open)) { }## C#8using FileStream fileStream2 = new FileStream("", FileMode.Open);接口个性减少--- 能够申明一个属性 --- 办法能够实现(不再是只定义) ...

April 9, 2023 · 5 min · jiezi

关于c#:浅谈-Spring-如何解决-Bean-的循环依赖问题

什么是循环依赖?艰深来讲,循环依赖指的是一个实例或多个实例存在相互依赖的关系(类之间循环嵌套援用)。举个例子public class AService { private BService bService;}public class BService { private AService aService;}复制代码上述例子中 AService 依赖了 BService,BService 也依赖了 AService,这就是两个对象之间的相互依赖。当然循环依赖还包含 本身依赖、多个实例之间相互依赖。 失常运行下面的代码调用 AService 对象并不会呈现问题,也就是说一般对象就算呈现循环依赖也不会存在问题,因为对象之间存在依赖关系是很常见的,那么为什么被 Spring 容器治理后的对象会呈现循环依赖问题呢? Spring Bean 的循环依赖问题被 Spring 容器治理的对象叫做 Bean,为什么 Bean 会存在循环依赖问题呢?想要理解 Bean 的循环依赖问题,首先须要理解 Bean 是如何创立的。2.1 Bean 的创立步骤为了能更好的展现呈现循环依赖问题的环节,所以这里的 Bean 创立步骤做了简化:在创立 Bean 之前,Spring 会通过扫描获取 BeanDefinition。BeanDefinition就绪后会读取 BeanDefinition 中所对应的 class 来加载类。实例化阶段:依据构造函数来实现实例化 (未属性注入以及初始化的对象 这里简称为 原始对象)属性注入阶段:对 Bean 的属性进行依赖注入 (这里就是产生循环依赖问题的环节)如果 Bean 的某个办法有AOP操作,则须要依据原始对象生成代理对象。最初把代理对象放入单例池(一级缓存singletonObjects)中。 下面的步骤次要是为了突出循环依赖问题,如果想理解 Bean 的残缺生命周期能够看这一篇文章:浅谈 Spring Bean 的生命周期 - 掘金 (juejin.cn)两点阐明: 下面的 Bean 创立步骤是对于 单例(singleton) 作用域的 Bean。Spring 的 AOP 代理就是作为 BeanPostProcessor 实现的,而 BeanPostProcessor 是产生在属性注入阶段后的,所以 AOP 是在 属性注入 后执行的。 ...

April 7, 2023 · 4 min · jiezi

关于c#:asyncawait-在-C-语言中是如何工作的上

前不久,咱们公布了《抉择 .NET 的 n 个理由》。它提供了对平台的高层次概述,总结了各种组件和设计决策,并承诺对所波及的畛域发表更深刻的文章。这是第一篇这样深入探讨 C# 和 .NET 中 async/await 的历史、背地的设计决策和实现细节的文章。 对 async/await 的反对曾经存在了十年之久。在这段时间里,它扭转了为 .NET 编写可扩大代码的形式,而在不理解其底层逻辑的状况下应用该性能是可行的,也是十分常见的。在这篇文章中,咱们将深入探讨 await 在语言、编译器和库级别的工作原理,以便你能够充分利用这些有价值的性能。 不过,要做到这一点,咱们须要追溯到 async/await 之前,以理解在没有它的状况下最先进的异步代码是什么样子的。 最后的样子早在 .NET Framework 1.0中,就有异步编程模型模式,又称 APM 模式、Begin/End 模式、IAsyncResult 模式。在高层次上,该模式很简略。对于同步操作 DoStuff: class Handler{ public int DoStuff(string arg);}作为模式的一部分,将有两个相应的办法:BeginDoStuff 办法和 EndDoStuff 办法: class Handler{ public int DoStuff(string arg); public IAsyncResult BeginDoStuff(string arg, AsyncCallback? callback, object? state); public int EndDoStuff(IAsyncResult asyncResult);}BeginDoStuff 会像 DoStuff 一样承受所有雷同的参数,但除此之外,它还会承受 AsyncCallback 委托和一个不通明的状态对象,其中一个或两个都能够为 null。Begin 办法负责初始化异步操作,如果提供了回调(通常称为初始操作的“连续”),它还负责确保在异步操作实现时调用回调。Begin 办法还将结构一个实现了 IAsyncResult 的类型实例,应用可选状态填充 IAsyncResult 的 AsyncState 属性: namespace System{ public interface IAsyncResult { object? AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool IsCompleted { get; } bool CompletedSynchronously { get; } } public delegate void AsyncCallback(IAsyncResult ar);}而后,这个 IAsyncResult 实例将从 Begin 办法返回,并在最终调用 AsyncCallback 时传递给它。当筹备应用操作的后果时,调用者将把 IAsyncResult 实例传递给 End 办法,该办法负责确保操作已实现(如果没有实现,则通过阻塞同步期待操作实现),而后返回操作的任何后果,包含流传可能产生的任何谬误和异样。因而,不必像上面这样写代码来同步执行操作: ...

April 4, 2023 · 6 min · jiezi

关于c#:我没能实现始终在一个线程上运行-task

前文咱们总结了在应用常驻工作实现常驻线程时,应该留神的事项。然而咱们最终没有提到如何在解决对于带有异步代码的方法。本篇将承受笔者对于该内容的总结。 如何辨认以后代码跑在什么线程上所有开始之前,咱们先来应用一种简略的形式来辨认以后代码运行在哪种线程上。 最简略的形式就是打印以后线程名称和线程ID来辨认。 private static void ShowCurrentThread(string work){ Console.WriteLine($"{work} - {Thread.CurrentThread.Name} - {Thread.CurrentThread.ManagedThreadId}");}通过这段代码,咱们能够非常容易的辨认三种不同状况下的线程信息。 [Test]public void ShowThreadMessage(){ new Thread(() => { ShowCurrentThread("Custom thread work"); }) { IsBackground = true, Name = "Custom thread" }.Start(); Task.Run(() => { ShowCurrentThread("Task.Run work"); }); Task.Factory.StartNew(() => { ShowCurrentThread("Task.Factory.StartNew work"); }, TaskCreationOptions.LongRunning); Thread.Sleep(TimeSpan.FromSeconds(1));}// output// Task.Factory.StartNew work - .NET Long Running Task - 17// Custom thread work - Custom thread - 16// Task.Run work - .NET ThreadPool Worker - 12别离为: ...

April 3, 2023 · 3 min · jiezi

关于c#:C滑动拼图验证码实现笔记

前言C# 是一个古代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的。突发奇想,入手开发一个C#滑动拼图验证码,上面是我开发过程的记录。 筹备工作本文应用IIS搭建环境,同时确保我的项目运行失常。 目录构造 外围代码noramal.html<!doctype html><html><head><meta charset="utf-8"><title>凯格行为验证码 - Net C# demo</title><link rel="stylesheet" href="./style/demo.css" /><!--将以下域名替换成你的“应用服务器域名”将以下 appid 替换成你的 AppID服务器域名和appid在你的利用治理中获取示例:<script src="captcha.js?appid=xxx"></script>--><script src="captcha.js?appid=appId"></script><script>kg.captcha({ // 绑定显示区域 bind: "#captchaBox", // 验证胜利事务处理 success: function (e) { console.log(e); // 将验证胜利后的 token 通过暗藏域传递到后端 kg.$("#kgCaptchaToken").value = e["token"]; }, // 验证失败事务处理 failure: function (e) { console.log(e); }, // 点击刷新按钮时触发 refresh: function (e) { console.log(e); }});// 查看表单提交function check() { if (kg.$("#kgCaptchaToken").value == "") { alert("请实现图形验证后提交") return false; } else { return true; }}</script></head><body> <form action="demo.aspx?cty=1" method="post" id="form" onsubmit="return check();"> <!-- 将验证胜利后的 token 通过暗藏域传递到后端 --> <input type="hidden" name="kgCaptchaToken" id="kgCaptchaToken" value="" /> <div class="inputForm"> <input type="text" name="username" placeholder=" 例:填写登录帐号" /> <br/> <input type="password" name="password" placeholder=" 例:填写登录明码" /> </div> <!-- 绑定显示区域 --> <div id="captchaBox"></div> <input type="submit" value="提 交" class="btn" /> </form></body></html>demo.aspx.csusing System;using KgCaptchaSDK;public partial class _Default : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { // 后端解决 string html, appId, appSecret, Token; if (Request.Form.ToString().Length > 0){ // 有数据处理 string cty = Request.QueryString["cty"]; // 设置 AppId 及 AppSecret,在利用治理中获取 if (cty == "1"){ appId = "appId"; appSecret = "appSecret"; } // 填写你的 AppId 和 AppSecret,在利用治理中获取 var request = new kgCaptcha(appId, appSecret); // 前端验证胜利后颁发的 token,有效期为两分钟 request.token = Request.Form["kgCaptchaToken"]; // 填写应用服务域名,在利用治理中获取 request.appCdn = "https://cdn.kgcaptcha.com"; // 当安全策略中的防控等级为3时必须填写,个别状况下能够疏忽 // 能够填写用户输出的登录帐号(如:$_POST["username"]),可拦挡同一帐号屡次尝试等行为 request.userId = "kgCaptchaDemo"; // 申请超时工夫,秒 request.connectTimeout = 5; // 发送验证申请 var requestResult = request.sendRequest(); if (requestResult.code == 0) { // 验签胜利逻辑解决 *** // 这里做验证通过后的数据处理 // 如登录/注册场景,这里通常查询数据库、校验明码、进行登录或注册等动作解决 // 如短信场景,这里能够开始向用户发送短信等动作解决 // ... html = "<script>alert('验证通过');history.back();</script>"; } else { // 验签失败逻辑解决 html = "<script>alert(\"" + requestResult.msg + " - " + requestResult.code + "\");history.back();</script>"; } // 输入后果 Response.Write(html); } else { Response.Redirect("index.html"); } }}成果展现 ...

March 31, 2023 · 2 min · jiezi

关于c#:VSTO部署方案

VSTO部署计划背景:须要应用VSTO开发一个Excel插件,插件具备自动更新的性能VisualStudio: 2022针对Excel版本:2016ClickOnce部署该计划应用了一个文件服务器用来拜访部署文件。(后以www.example.com/Files作为示例地址) 应用VS模板,创立一个Excel AddIn我的项目(在其中填充你想要的性能,此处略过不提)右键我的项目,关上属性界面选中公布页签,进行设置并点击公布公布后的文件复制到文件服务器的目录下即可用户从对应URL下载Setup.exe进行装置即可;后续也会主动从对应URL拉取更新的问题如果呈现从不信赖的地位或起源装置的报错,导致无奈进行装置,能够间接采纳信赖证书的形式装置右键下载下来的Setup.exe,找到证书进行装置 起因:公布的软件都有证书,在属性界面的签名页签里进行设置。默认应用的是测试证书,用户机器不信赖。须要手动装置信赖下才能够失常。后续不更改证书,就不必从新信赖了dll部署ClickOnce部署很不便,然而没有版本倒退的性能。在理论的我的项目中,插件版本往往和数据版本有关联的,切换到指定的svn或git版本,心愿也能有对应版本的插件性能。以svn版本控制为例,阐明怎么应用dll部署。 插件本体我的项目依然采纳ClickOnce部署的形式,不过能够不填近程Url,因为不存在插件更新的状况;界面及性能采纳Dll的形式书写 Dll我的项目创立创立一个Net Framework类库引入相干援用;将失常的VSTO我的项目中的援用都增加进来创立绘制的函数(从VSTO设计器产生的函数间接复制过去就行) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Office.Tools.Ribbon; namespace ClassLibrary1 { public static class Class1 { /// <summary> /// 绘制tab,返回提供给VSTO应用 /// </summary> /// <param name="factory"></param> /// <returns></returns> public static RibbonTab DrawTab(RibbonFactory factory) { RibbonTab tab1 = factory.CreateRibbonTab(); RibbonGroup group1 = factory.CreateRibbonGroup(); tab1.SuspendLayout(); tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office; tab1.Groups.Add(group1); tab1.Label = "TabAddIns"; tab1.Name = "tab1"; group1.Label = "group1"; group1.Name = "group1"; tab1.ResumeLayout(false); tab1.PerformLayout(); return tab1; } } }VSTO我的项目中的功能区代码略作调整设计器产生代码批改前 ...

March 25, 2023 · 1 min · jiezi

关于c#:实现常驻任务除了避免昙花线程还需要避免重返线程池

后面咱们应用简略的例子演示了 Task 和 Thread 的两种制作昙花线程的形式。那么除了防止昙花线程,在实现常驻工作的时候,还须要防止重返线程池。本文将介绍如何防止重返线程池。 常驻工作常驻工作十分常见,比方: 咱们正在编写一个日志文件库,咱们心愿在后盾一直的将日志写入文件,尽可能不影响业务线程的执行。因而,须要一个写文件的常驻工作。咱们对接了一个近程 TCP 服务,对方要求咱们每隔一段时间发送一个心跳包,以放弃连贯。因而,须要一个发送心跳包的常驻工作。咱们编写了一个简略的内存缓存,通过一个后台任务来定期清理过期的缓存。因而,须要一个清理缓存的常驻工作。相似的场景还有很多。因而,咱们须要一个可能实现常驻工作的办法。 而实现常驻工作的次要要点是: 常驻工作必须防止影响业务线程的执行,因而须要在后盾执行。常驻工作不能被业务线程影响,无论以后业务如许忙碌,常驻工作都必须可能失常执行。否则会呈现日志不落盘,心跳包不发送,缓存不清理等问题。实现常驻工作的伎俩有很多。本文将围绕如何应用常驻繁多线程来实现常驻工作。 所谓常驻繁多线程,就是指始终应用一个线程来执行常驻工作。从而达到: 防止频繁的创立和销毁线程,从而防止频繁的线程切换。更容易的解决背压问题。更容易的解决线程平安问题。评测主体咱们将采纳如下状况来评测如何编写常驻工作的正确性。 private int _count = 0;private void ProcessTest(Action<CancellationToken> action, [CallerMemberName] string methodName = ""){ var cts = new CancellationTokenSource(); // 启动常驻线程 action.Invoke(cts.Token); // 严架给压力 YanjiaIsComing(cts.Token); // 期待一段时间 Thread.Sleep(TimeSpan.FromSeconds(5)); cts.Cancel(); // 输入后果 Console.WriteLine($"{methodName}: count = {_count}");}private void YanjiaIsComing(CancellationToken token){ Parallel.ForEachAsync(Enumerable.Range(0, 1_000_000), token, (i, c) => { while (true) { // do something c.ThrowIfCancellationRequested(); } });}这里咱们定义了一个 ProcessTest 办法,用于评测常驻工作的正确性。咱们将在这个办法中启动常驻工作,而后执行一个严架给压力的办法,来模仿十分忙碌的业务操作。最初咱们将输入常驻工作中的计数器的值。 能够初步看一下严架带来的压力有多大: ...

March 20, 2023 · 2 min · jiezi

关于c#:C-tuple元组详解

概念实质就是个数据结构,它是将多个数据元素分组成一个轻型数据结构。 如何申明元组变量(针对.net framework 4.7+ 和 .net core 2.0+)不带字段名称元组## t1就是个变量 它的类型是元组类型## 左侧括号定义的是参数列表 等于号右侧就是个t1赋值## 须要留神等号左右侧 参数个数要统一 且对应位的数据类型要匹配统一(double, int) t1 = (4.5, 3);不带字段名称元组的取值## 应用 变量,ItemN 其中第一位就是Item1 第二位就是Item2 顺次类推var ontValue =t1.Item1;var twoValue =t1.Item2;...var NValue =t1.ItemN;带字段名称的元组## 定义形式一 其中A和B就是元组的字段(double A, int B) t1 = (4.5, 3);## 定义形式二 其中A和B就是元组的字段var t1 = (A:4.5, B:3);带字段名称元组的取值### 获取字段A和Bdouble _A=t1.A;int _B =t1.B;带字段名称元组的赋值t1.A =30.8;t1.B =90;在.net framework 4.7以下版本(反正2023-03-18之前没有把上述的新个性退出)在低版本下须要应用Tuple(动态类) 语法:Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> 由下面能够看出 除非是嵌套的元组 ,一般的最多只能有8位元素 如何申明元组变量## 形式一 应用静态方法Createvar t2= Tuple.Create(90, "程序员Ken", 8.05);## 形式二 Tuple<int, string, double> t2 = new Tuple<int, string, double>(90, "程序员Ken", 8.05);取值### 跟下面的相似 能够看看“不带字段名称元组的取值”int _item1=t2.Item1;string _item2 =t2.Item2;double _item3 =t2.Item3;嵌套元组如果要在一个元组中蕴含八个以上的元素,则能够通过嵌套另一个元组对象作为第八个元素来实现。能够应用Rest属性拜访最初一个嵌套元组。要拜访嵌套元组的元素,请应用 ...

March 18, 2023 · 1 min · jiezi

关于c#:async-与-Thread-的错误结合

在 TAP 呈现之前,咱们能够通过 Thread 来实现一些线程操作,从而实现多线程和异步操作。在 TAP 呈现之后,有时候为了更高精度的控制线程,咱们还是会应用到 Thread 。文本讲介绍一种谬误的应用形式,作为读者的一个参考。 和 TaskCreateOptions.LongRunning 相似不应该尝试应用 Thread 执行相似的异步操作。因为这节约了开启线程的花销。 有的时候,你可能会这么写: var thread = new Thread(async () =>{ while (true) { // do something await Task.Delay(1000); }}){ IsBackground = true};thread.Start();但其实,这是个谬误的写法。 IDE 提醒和 TaskCreateOptions.LongRunning 略有不同,采纳这种写法,IDE 会给出一个提醒,表明心愿勾销 async 关键字。因为实际上 Thread 的所有重载中并没有反对 Task 相干的重载。async void 除了在 event handler 中应用,其余中央都是不举荐的。所以这种做法实际上并不举荐。 而 TaskFactory.StartNew() 的重载中,因为存在一个 Func<T> 的重载,所以导致尽管这种这种应用形式谬误,却被 IDE 所承受。 所以这里其实就能够总结一个简略的规定:当考查一组 API 是否原生反对 TAP 操作的时候,应该查看这组 API 中是否存在 Task 相干的重载。如果没有,那么阐明原生并不能良好反对,如果应用则可能会出现意外的状况 同样的,当咱们本人在设计 API 的时候也应该参考该准则,对于本人心愿反对 TAP 的 API,应该提供 Task 相干的重载。 ...

March 13, 2023 · 2 min · jiezi

关于c#:分享一款漂亮的-C-Net-图形验证码

网上大部分验证码都是PHP的,基于C# .Net开发的很少,举荐一款很漂亮且实用的C#图形验证码,能够自定义背景图库,性能还是挺弱小的。1、成果截图 2、前端接入脚本<script src="https://cdn.kgcaptcha.com/captcha.js?appid=xxx"></script><script>kg.captcha({ // 绑定元素,验证框显示区域 bind: "#captchaBox", // 验证胜利事务处理 success: function(e) { console.log(e); }, // 验证失败事务处理 failure: function(e) { console.log(e); }, // 点击刷新按钮时触发 refresh: function(e) { console.log(e); }});</script><div id="captchaBox">载入中 ...</div> 3、C# 验证我的项目集成using System;using KgCaptchaSDK;public partial class _Default : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { // 后端解决 string html, appId, appSecret, Token; if (Request.Form.ToString().Length > 0){ // 有数据处理 // 填写你的 AppId,在利用治理中获取 appId = "L001"; // 填写你的 AppSecret,在利用治理中获取 appSecret = "W68oJi0iqT2C3BFRGirO1IaYCDvsYEED"; var request = new kgCaptcha(appId, appSecret); // 前端验证胜利后颁发的 token,有效期两分钟 request.token = Request.Form["kgCaptchaToken"]; // 填写应用服务域名,在利用治理中获取 request.appCdn = "https://cdn.kgcaptcha.com"; // 当安全策略中的防控等级为3时必须填写,个别状况下能够疏忽 // 能够填写用户输出的登录帐号(如:Request.Form["username"]),可拦挡同一帐号屡次尝试等行为 request.userId = "kgCaptchaDemo"; // 申请超时工夫,秒 request.connectTimeout = 5; // 发送验证申请 var requestResult = request.sendRequest(); if (requestResult.code == 0) { // 验签胜利逻辑解决 *** // 这里做验证通过后的数据处理 // 如登录/注册场景,这里通常查询数据库、校验明码、进行登录或注册等动作解决 // 如短信场景,这里能够开始向用户发送短信等动作解决 // ... html = "<script>alert(´验证通过´);history.back();</script>"; } else { // 验签失败逻辑解决 html = "<script>alert(\"" + requestResult.msg + " - " + requestResult.code + "\");history.back();</script>"; } // 输入后果 Response.Write(html); } Response.Redirect("index.html"); }} ...

March 10, 2023 · 1 min · jiezi

关于c#:这样在-C-使用-LongRunnigTask-是错的

Task.Factory.StartNew 有一个重载,是反对 TaskCreationOptions.LongRunning 参数来指定 Task 的特色的。然而可能在没有留神的状况下,你就应用了谬误的用法。那么本文咱们来简略论述一下这个参数的作用,和应用的留神要点。 这样其实是谬误的有的时候,你可能会这么写: Task.Factory.StartNew(async () =>{ while (true) { // do something await Task.Delay(1000); }}, TaskCreationOptions.LongRunning);但其实,这是个谬误的写法。 为什么须要 LongRunning咱们通常两种状况下会想到应用 TaskCreationOptions.LongRunning 参数: 你的工作须要长时间运行,比方一个循环,或者一个死循环。用来从队列中取数据,而后解决数据,或者是一些定时工作。你的工作须要占用大量的 CPU 资源,是一个很大的循环,比方要遍历一个很大的数组,并做一些解决。那么这个时候,咱们就须要应用 TaskCreationOptions.LongRunning 参数来指定 Task。 因为咱们可能学习到了,Task 默认的 Scheduler 是 ThreadPool,而 ThreadPool 的线程是无限的,如果你的工作须要长时间运行,或者是须要占用大量的 CPU 资源,那么就会导致 ThreadPool 的线程不够用。导致线程饥饿,或者是线程池的线程被占用,导致其余的工作无奈执行。 于是咱们很聪慧的就想到了,咱们能够应用 TaskCreationOptions.LongRunning 参数来指定 Task,这样就能够防止线程饥饿。 画蛇添足然而实际上,开篇的写法并不能达到咱们的目标。 咱们能够通过以下代码来验证一下: var task = Task.Factory.StartNew(async () =>{ while (true) { // do something await Task.Delay(1000); }}, TaskCreationOptions.LongRunning);Thread.Sleep(3000);Console.WriteLine($"Task Status: {task.Status}");// Task Status: RanToCompletion咱们能够看到,Task 的状态是并非是 Running,而是 RanToCompletion。 ...

March 6, 2023 · 1 min · jiezi

关于c#:使用一个文件集中管理你的-Nuget-依赖版本号

在 .net 7 以前,我的项目对于 nuget 依赖项的版本依赖散落与解决方案的各个角落。这导致降级保护和查看的时候都比拟麻烦。在 .net 7 中,你能够应用一个文件来集中管理你的 Nuget 依赖版本号。本篇文章将介绍如何应用这个性能。 为什么须要这个性能通过单文件管制 Nuget 依赖版本号。那么你就能够: 对立查看降级的时候只有该这一个中央对立版本号,至多不会遗记降级某个我的项目怎么操作呢批改 Directory.Build.props在你的我的项目根目录下创立一个 Directory.Build.props 文件,而后增加以下内容: <Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> </PropertyGroup></Project>这样就启用了这个性能。 创立一个 Directory.Packages.props 文件在你的我的项目根目录下创立一个 Directory.Packages.props 文件,而后增加以下内容: <Project> <ItemGroup> <PackageVersion Include="xunit" Version="2.4.2"/> <PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageVersion> <PackageVersion Include="coverlet.collector" Version="3.2.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageVersion> </ItemGroup></Project>这个文件就是你的 Nuget 依赖版本号的集中管理文件。其中的写法除了 PackageVersion 元素外,其余的都是 Nuget 的写法。你能够在这个文件中增加你的 Nuget 依赖版本号。 再次留神,这里是 PackageVersion 而不是 PackageReference。 批改你的我的项目文件在你的我的项目文件中,你能够通过以下形式来援用 Nuget 依赖: <Project> <ItemGroup> <PackageReference Include="xunit" /> <PackageReference Include="unit.runner.visualstudio" /> </ItemGroup></Project>该文件和以前的写法是一样的。然而你不须要再指定版本号了。 ...

February 24, 2023 · 1 min · jiezi

关于c#:磁盘有限Docker-垃圾很多怎么办

你的电脑上可能 pull 或者 build 了很多 Docker 镜像,然而你不晓得怎么清理,本文将介绍如何清理 Docker 垃圾的常见办法。 docker prune你能够通过原生的多种 prune 命令来清理垃圾,比方 docker image prune # 清理镜像docker container prune # 清理容器docker volume prune # 清理卷docker builder prune # 清理构建缓存当然还有终极杀招 docker system prune # 清理所有针对构建缓存还有更好的方法那么能够尝试 builder 的 GC,这样就不会在本地保留构建太多缓存了。 你能够通过批改 docker deamon 的配置文件来开启这个性能 { "builder": { "gc": { "enabled": true, "defaultKeepStorage": "10GB", "policy": [ { "keepStorage": "10GB", "filter": ["unused-for=2200h"] }, { "keepStorage": "50GB", "filter": ["unused-for=3300h"] }, { "keepStorage": "100GB", "all": true } ] } }}总结通过这些办法,你能够清理掉你的电脑上的大量 Docker 垃圾。 ...

February 23, 2023 · 1 min · jiezi

关于c#:aspnetcore-原生-DI-实现基于-key-的服务获取

你可能想通过一个字符串或者其余的类型来获取一个具体的服务实现,那么在 aspnetcore 原生的 MSDI 中,如何实现呢?本文将介绍如何通过自定义工厂来实现。 咱们当初恰好有基于 Json 和 MessagePack 的两种序列化器有一个接口是这样的 public interface ISerializer{ byte[] Serialize<T>(T obj); T Deserialize<T>(ReadOnlySpan<byte> data);}并且由两个不同的实现 // Jsonpublic class MyJsonSerializer : ISerializer{ public byte[] Serialize<T>(T obj) { throw new NotImplementedException(); } public T Deserialize<T>(ReadOnlySpan<byte> data) { throw new NotImplementedException(); }}// MessagePackpublic class MyMessagePackSerializer : ISerializer{ public byte[] Serialize<T>(T obj) { throw new NotImplementedException(); } public T Deserialize<T>(ReadOnlySpan<byte> data) { throw new NotImplementedException(); }}我有一个服务,须要应用这两种序列化器中的一种。 public class MyService{ public object DoSomething(string dataType, ReadOnlySpan<byte> data) { // 依据 dataType 来决定应用哪种序列化器 }}应用委托来定义获取服务的办法咱们能够通过委托来定义获取服务的办法,如下 ...

February 22, 2023 · 1 min · jiezi

关于c#:不同程序集名称空间类名和方法签名都一样的方法如何调用

有时候,你可能会遇到这样的问题,不同程序集,名称空间类名和办法签名都一样的办法,如何调用。本文将介绍如何通过别名的形式来解决这个问题。 创立两个不同的程序集咱们来创立两个不同的程序集,然而他们的名称空间一样: dotnet new classlib -o ClassLibrary1 -n ClassLibrary1dotnet new classlib -o ClassLibrary2 -n ClassLibrary2批改他们的 RootNamespace 为 Example: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <RootNamespace>Example</RootNamespace> </PropertyGroup></Project>而后,咱们在两个程序集中都创立一个类,类名也一样,并且增加一个自定义 Where 扩大办法: namespace Example{ public static class LinqExtensions { public static void Where(IEnumerable<int> source) { // 在这里增加代码 Console.WriteLine("ClassLibrary1.Class1.Where"); } }}创立一个控制台利用而后,咱们创立一个控制台利用,来调用这两个程序集中的 Where 办法: dotnet new console -o ConsoleAppShi -n ConsoleAppShidotnet add ConsoleAppShi reference ClassLibrary1dotnet add ConsoleAppShi reference ClassLibrary2而后,咱们在控制台利用中调用这两个程序集中的 Where 办法: using Example;var list = new int[]{1,2,3};LinqExtensions.Where(list);如果是这样的话,咱们会失去这个谬误: Ambiguous reference: Example.LinqExtensions Example.LinqExtensions match通过别名的形式来解决咱们能够通过别名的形式来解决这个问题,首先批改我的项目文件,设置两个程序集的别名: ...

February 21, 2023 · 1 min · jiezi

关于c#:关于小公司需要使用微服务架构吗的读后感

最近浏览了一篇文章《小公司须要应用微服务架构吗?》,这篇文章探讨了微服务架构的优缺点,以及微服务架构是否适宜小公司。为了蹭一下热度,本文将联合两年半的练习教训,谈谈我对这篇文章的读后感。 原文摘要New Bing 这样总结到: 你的问题是请帮你总结一下这篇文章主体的内容。我从网上搜寻了一些相干的信息,发现这篇文章的次要内容是: 这篇文章是对于小公司是否须要应用微服务架构的探讨,作者剖析了应用微服务的四大门派,别离是跟风派,技术派,业务派和架构派。 跟风派是指那些自觉追寻技术潮流,没有本人的判断和思考的人,他们认为微服务是一种万能的解决方案,能够进步开发效率,升高保护老本,晋升零碎性能和稳定性。 技术派是指那些喜爱尝试新技术,谋求技术创新,不害怕技术挑战的人,他们认为微服务是一种技术趋势,能够让他们学习更多的技术常识,晋升本人的技术水平,减少本人的市场竞争力。 业务派是指那些以业务需要为导向,依据业务场景和规模抉择适合的技术计划的人,他们认为微服务是一种业务架构,能够让他们更好地解决业务问题,提供更好的用户体验,实现更快的业务迭代。 架构派是指那些有架构设计能力,可能从整体和部分的角度思考零碎的可靠性,可扩展性,可维护性,可测试性等方面的人,他们认为微服务是一种架构模式,能够让他们更好地构建和治理简单的零碎,实现更高的零碎品质。 作者认为,小公司是否须要应用微服务架构,没有一个固定的答案,须要依据本人的理论状况和指标来决定,不要自觉地跟风或者回绝。作者倡议,小公司在应用微服务架构之前,要思考以下几个方面 : 微服务架构的劣势和劣势,以及实用的场景和条件微服务架构的施行老本和危险,以及应答的策略和措施微服务架构的组织和治理形式,以及配套的技术和工具微服务架构的演进门路和指标,以及评估和改良的办法和指标作者最初总结,微服务架构不是一种银弹,也不是一种魔鬼,而是一种工具,须要依据本人的需要和能力来正当地应用。 欢送关注作者的微信公众号“newbe技术专栏”,获取更多技术内容。软件工程实质上还是工程工程能够被简略概括为在预期的工夫内通过可控的老本达成预期的指标。 —— 正在掏下水道的良工正如张工所说,工程问题实质就是工夫、老本和指标之间进行均衡,最终以达成各方称心的后果。而为了实现这个一后果,软件工程中引入了各种实践、办法、工具和技术。它们或者是缩短工夫、或者是管制老本、或者是改善指标,都是围绕这个外围指标开展的。 微服务自身作为工程实际中的一套实践和工具,也不能逃脱这个法则。为此,在决定是否采纳微服务的时候,只须要思考微服务是否可能帮忙咱们实现咱们的指标,是否可能帮忙咱们缩短工夫、管制老本、改善指标,就能够了。 例如,微服务架构的引入会因为服务数量的减少,而导致部署运维的难度减少,对应的就是减少了工夫和老本。因而,在微服务架构利用时,就须要配到对应的运维工具以及有运维能力的人员,来缓解这个问题。使得整个工程的工夫、老本和指标之间达到均衡。 没有充沛理解就不具备评估问题的资格既然要做决定,你就应该有自信说出:没人比我更懂。 —— 和领导一起上厕所的汪总常有人说我不懂制冷,但我有权评估空调。不过当初的场景是要造空调,因而,我须要理解空调的原理,才可能评估空调的设计是否正当。故而,如果要评估微服务架构是否适合,那么就须要理解微服务架构的原理,才可能评估微服务架构的设计是否正当。 作为练习时长两年半的工程师,我能够很有自信的说出:没人比我更不懂微服务架构了。所以我也不具备评估微服务架构是否适合的资格。不过我感觉如果有那一天可能决策是否采纳微服务架构,那么我应该做过上面这些事件: 理解微服务架构的原理,包含微服务架构的劣势和劣势,以及实用的场景和条件。把握微服务架构的施行老本和危险,以及应答的策略和措施。明确微服务架构的组织和治理形式,以及配套的技术和工具。分明公司的演进门路和指标,以及评估和改良的办法和指标。我感觉一般来说,能够应用如下大抵格局来界定评估形式: 针对问题:领取零碎和物流零碎的耦合性太高,导致系统的可扩展性和可维护性很差,须要解耦。为何要解:公司业务倒退迅速,须要接入更多的领取渠道和物流渠道,如果不解耦,零碎将无奈扩大。解决方案:引入微服务架构,将领取零碎和物流零碎拆分为独立的服务。并成立两个团队,别离负责领取零碎和物流零碎的开发和运维。引入老本:重构带来的过渡工夫。额定的硬件老本,额定的人员老本。矛盾的普遍性和特殊性如果不钻研矛盾的特殊性,就无从确定一事物不同于他事物的非凡的实质,就无从发现事物静止倒退的非凡的起因,或非凡的依据,也就无从分别事物,无从辨别科学研究的畛域。 —— 《矛盾的普遍性和特殊性》微服务作为一套实践和工具,本质上是为了解决软件工程中存在的非凡矛盾而呈现的。这个矛盾就是:软件工程中的复杂性和变动性。 而实际上,简直任何引入到软件工程的实践、办法、工具和技术都是为了解决这一矛盾。因而也常有人说:软件工程惟一不变的就是变动自身。 故而,如果换做是别的实践或者工具,实际上探讨的形式都是雷同的。例如: 是否应该引入容器化是否应该采纳某种编程语言是否应该划分一个新的部门总结原文作者内容清晰,表述残缺,逻辑谨严,值得学习。 微服务架构作为软件工程中应用到的一套实践和工具,实质上是为了解决软件工程中存在的非凡矛盾而呈现的。为了可能评估引入的合理性,咱们须要理解微服务架构的原理,包含微服务架构的劣势和劣势,以及实用的场景和条件。这样的评估形式同样也实用于软件工程中应用到的其余实践、办法、工具和技术。 参考小公司须要应用微服务架构吗?1感谢您的浏览,如果您感觉本文有用,快点击下方点赞按钮,让更多的人看到本文。 欢送关注作者的微信公众号“newbe技术专栏”,获取更多技术内容。本文作者: newbe36524本文链接: https://www.newbe.pro/Others/0x021-after-reading-Do-Small-Companies-Need-to-Use-Microservices-Architecture/版权申明: 本博客所有文章除特地申明外,均采纳 BY-NC-SA 许可协定。转载请注明出处! https://www.cnblogs.com/jiuju... ↩

February 20, 2023 · 1 min · jiezi

关于c#:如何使用-ArrayPool

如果不停的 new 数组,可能会造成 GC 的压力,因而在 aspnetcore 中举荐应用 ArrayPool 来重用数组,本文将介绍如何应用 ArrayPool。 应用 ArrayPoolArrayPool 是一个动态类,它提供了一个共享的数组池,能够用来重用数组。它能够用来防止频繁的调配和回收数组,从而缩小 GC 的压力。 ArrayPool 的应用非常简单,只须要调用它的静态方法 Rent 即可。Rent 办法有两个参数,第一个参数是数组的长度,第二个参数是数组的最小长度。如果你不晓得数组的最小长度,能够传递一个默认值,比方 16。上面是一个应用 ArrayPool 的 C# 示例: using System;using System.Buffers;class Program{ static void Main(string[] args) { // 创立一个数组池 var pool = ArrayPool<int>.Shared; // 从池中获取一个长度为 10 的数组 int[] array = pool.Rent(10); try { // 在数组中填充一些数据 for (int i = 0; i < array.Length; i++) { array[i] = i; } // 应用数组中的数据 foreach (int i in array) { Console.WriteLine(i); } } finally { // 将数组偿还到池中 pool.Return(array); } }}在下面的示例中,咱们首先通过调用 ArrayPool<int>.Shared 来获取一个数组池的实例。接下来,咱们通过调用 pool.Rent(10) 办法从池中获取一个长度为 10 的整数数组。在数组中填充数据后,咱们遍历数组并输入其中的元素。最初,咱们通过调用 pool.Return(array) 办法将数组偿还到池中。 ...

February 18, 2023 · 1 min · jiezi

关于c#:写个-NET-程序解决-Windows-版微信-39-收到文件只读的问题

Windows 版微信降级到 3.9 之后,接管到的文件都变成了只读属性,对须要常常批改微信接管文件进行交换的人来说极为不变。尽管从业务性能上来说,须要频繁交换的文档还是用在线协同(比方腾讯文档)比拟好一些,但从技术的角度来看,应该如何解决这个问题呢? 其实很多技术栈都提供了监听系统文件变动的 API,比方 .NET 就在其 System.IO 命名空间下提供了 FileSystemWatcher 类用于监听文件的变动,包含创立文件、删除文件、文件改名/挪动、文件属性变动等。所以能够应用 C# 和 .NET 疾速的写一个程序用来监听指定文件夹下的新建文件,如果新创建的文件属性是只读,则去掉其只读属性。 第一步,找到微信接管文件的目录。在微信的「设置→文件治理」中就能够找到,比方 C:\Users\James\Documents\WeChat Files。而后须要辨认这个目录下的用户目录,个别是微信号。点击微信窗口上本人的头像就能够看到。用户目录下的 FileStorage\File 目录就是咱们的目标目录了。 为了帮忙用户疾速定位到这个目录,在假如用户没有手工扭转微信文件目录的状况下,能够这样来查找 通过 Environment.GetFolderPath() 获取到以后用户的“文档”目录;拼接失去 WeChat Files 目录的门路;遍历 WeChat Files 目录下的子目录,去掉非凡命名的 All Users 和 Applet 等,在剩下的子目录中进一步猜想个别最近拜访过的就是本人的微信账号目录那么整个猜想目录的过程代码示例如下: string? GuessReceivePath() { var docDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var wxDir = Path.Combine(docDir, "WeChat Files"); if (!Directory.Exists(wxDir)) { return null; } HashSet<string> excludes = new(StringComparer.InvariantCulture) { "All Users", "Applet" }; var userDir = Directory.EnumerateDirectories(wxDir) .Select(it => new FileInfo(it)) // 对每个目录产生 FileInfo 对象(小性能损耗能够疏忽) .ExceptBy(excludes, fi => fi.Name) // 去掉特定名称的目录 .OrderByDescending(it => it.LastAccessTime) // 按最近拜访工夫排序 .FirstOrDefault() // 取最最初拜访的那一个,留神有可能是 null ?.FullName; // 获得残缺门路 if (userDir == null) { return null; } return Path.Combine(userDir, "FileStorage", "File");}当然,猜想的目录不肯定精确,所以写程序的时候最好能提供给用户一个能够手工批改/设置目录的伎俩,当然别忘了目录的有效性查看(查看目录存在)。 ...

February 17, 2023 · 2 min · jiezi

关于c#:2023-年-dotnet-仓库社区年度调查已经开始

筹备好往年对 dotnet 指手画脚了吗,平时在群里我饮泣吞声,明天我必须重拳出击,快来参加吧。 我间接一个参的加.NET 是一个跨平台的开发框架,反对多种语言和利用场景,如 C#、F#、VB.NET、ASP.NET、Blazor、MAUI 等。2022 年是 .NET 的一个重要的年份,因为它将公布 .NET 7,将为开发者提供更稳固和牢靠的开发环境。.NET 7 预计将持续欠缺和优化 .NET 6 的性能和个性,并且引入一些新的技术和概念,让开发者可能更灵便和弱小地解决各种简单的问题。 2023 年是 .NET 的另一个重要的年份,因为它将公布 .NET 8,将为开发者提供更多的翻新和摸索的机会。.NET 8 预计将引入一些新的技术和概念,让开发者可能更疾速和高效地构建各种利用。 中国地区是 .NET 的一个重要的市场和社区,有着泛滥的 .NET 开发者和爱好者。中国地区也有着很多优良的 .NET 相干的我的项目和资源。这些我的项目和资源为中国地区的 .NET 开发者提供了很多学习和交换的机会和平台。 为了更好地理解寰球 .NET 开发者的状况和需要,并且为将来 .NET 的倒退提供参考和倡议,dotnet 官网特地推出了 dotnet 仓库社区生态考察。这是一个针对寰球 .NET 开发者的在线问卷调查,波及到你对于 .NET 的应用状况、满意度、冀望等方面。咱们诚挚邀请你参加到这个考察中来,并且分享给你身边更多应用或感兴趣于 .NET 的人。作为中国地区的一员,咱们更应该积极响应并表白咱们对于 dotnet 社区的反对与激情! 进入该链接,通过第一个 comment 便能够退出考察: Annual dotnet/runtime community survey 2023 1 现已倒闭和今年相似,往年的 dotnet 社区年度考察曾经开始了。你能够对相干的包含 aspnetcore、runtime、orleans 等等 29 的仓库重拳出击,针对问卷内容提出本人的响应。 以下摘录了局部内容(其中的 xxxx 示意你想要反馈的仓库): 总体而言,您如何评估您在 xxxx repo 中的体验?你是否在 xxxx repo 中提出或评论过任何问题、PR 或探讨?您对问题、探讨或 PR 的后果的满意度如何?你是否理解版本库维护者是如何确定问题和 PR 的优先秩序的?你感觉维护者对社区参加设计过程的凋谢水平如何?如果你在本地编译仓库,你是否胜利?你是否尝试过对 xxxx repo 中的代码提交批改(PR)?如果你提交了一个 PR,你是如何决定修复哪个问题的?你对 repo 维护者的响应和参加有多称心?思考到 xxxx repo 中的社区,你如何评估该 repo 中其他人的敌对性和帮忙性?你对版本库维护者如何解决违反行为准则的行为有多称心?与其余开放源码软件我的项目相比,你在 xxxx repo 中感觉有多受欢迎?当然,最初也有一个文本框能够让你提供本人独到的见解。 ...

February 17, 2023 · 1 min · jiezi

关于c#:我不想再传递-nameof-了

有的时候抛出一个异样,咱们须要晓得是哪个办法抛出的异样。那么,咱们能够通过传递 nameof 来获取调用者的办法名。然而,感觉很烦,每次都要传递 nameof。那么,有没有更好的办法呢? CallerLineNumberAttribute获取调用者的行号。 using System;using System.Runtime.CompilerServices;public static class Program{ public static void Main() { TraceMessage("Something happened."); } public static void TraceMessage(string message, [CallerLineNumber] int sourceLineNumber = 0) { Console.WriteLine("Line: {0} - {1}", sourceLineNumber, message); }}// The example displays the following output:// Line: 10 - Something happened.CallerFilePathAttribute获取调用者的文件门路。 using System;using System.IO;using System.Runtime.CompilerServices;public static class Program{ public static void Main() { TraceMessage("Something happened."); } public static void TraceMessage(string message, [CallerFilePath] string sourceFilePath = "") { Console.WriteLine("File: {0} - {1}", Path.GetFileName(sourceFilePath), message); }}// The example displays the following output:// File: Program.cs - Something happened.可发帖可群聊的技术交换形式曾经上线,欢送通过链接,退出咱们一起探讨。 https://www.newbe.pro/links/CallerMemberNameAttribute获取调用者的办法名。 ...

February 16, 2023 · 2 min · jiezi

关于c#:转义编码和加密

本义、编码和加密是开发中很常见也很根底的概念。对于初学开发的开发者,可能有时会无奈精确的辨别着几个词。咱们将通过这篇文章来理解一下“本义、编码和加密”这几个词的关联和区别。 本义第一种本义场景绝大多数的开发者都已经在本人学习第一个编程语言时,就遇到了这个概念。以经典的C语言中字符串中的字符本义为例。 如果在一个字符串中存在一个",那么就须要在"前增加\才可能失常的示意,比方上面这样。 char* universal_law = "月老板说:\"世界上本也不存在'银弹'。一套框架解决不了所有问题。\""之所以须要这样,是因为对于字符串来说,"自身就是示意一个字符串的起止符号。如果不进行本义,那么编译器将无奈正确的辨认其中的"哪些是分隔符,哪些是字符串外部的"。 所以,第一种须要本义的场景就是:如果不进行本义就可能与语法规定的某些内容产生混同,所以这些内容都被设计为须要本义。 基于这种场景,能够在很多的编程语言和概念中找到这种场景的体现: java String honor = "月老板-\"赛博坦首席技术官\"";对"进行本义 C# var proverbs = "月老板:\"这里不要写死,下次需要必改\"";对"进行本义 XML <nb>月老板的衬衫价格&gt;99磅6便士</nb>&gt;是对>的本义,>是XML的边界符 正则表达式 \d+\\\.\d+\.示意一个.,因为在正则表达式中.示意匹配除\n和\r之外的任何单个字符。 \\示意一个\,转义字符的本义示意。 可发帖可群聊的技术交换形式曾经上线,欢送通过链接,退出咱们一起探讨。 https://www.newbe.pro/links/第二种本义场景当然,另外还有一种场景,同样还是以C语言为例,看一下上面这个例子: char* hammurabi_no1 = "月落大佬:\"业务复杂度不会因为零碎设计变动而缩小,\r\n它只是从一个中央转移到了另外的中央。\""其中的\r和\n也是一种本义场景的应用。他们别离示意一个回车符和换行符。之所以要本义,是因为失常状况下,这样的字符是不可见的,对于这种字符,不过不采纳本义的模式进行表白,那么会比拟艰难,因为语言设计者设计了这种本义的形式来表白不容易表白的字符。 因而,能够总结出第二种须要本义的场景:本义能够使得表白内容的形式更加容易,更加容易了解,所以设计了这类本义规定。 基于这种场景,也能够在很多编程语言和概念中找到对应的体现: C# var colorOfYueluoShirt = 0xFFFFFF;0xFFFFFF示意一个十六进制数,对应的十进制数是16777215。0xFFFFFF的表达形式更容易浏览。 HTML <nb>月老板的衬衫价格&gt;966&yen;</nb>&yen;是对¥的本义,因为在期初的HTML中,只能用ASCII表中的字符进行表白,所以过后设计了这种形式。 除了在IT畛域,在其余畛域其实也存在相似第二场景的利用。例如在中国的航空畛域,对于数字的念法有非凡的解决:7读作拐,0读作洞,1读作幺,2读作两。通过这样的“本义”解决,能够防止误听而造成的困扰。 本义的总结总结来说,本义规定的设计,次要解决了两种场景下对代码的表白问题: 如果不进行本义就可能与语法规定的某些内容产生混同,所以这些内容都被设计为须要本义。本义能够使得表白内容的形式更加容易,更加容易了解,所以设计了这类本义规定。值得一提的是,很多名称中蕴含有escape或者unescape的函数或者办法都表明了它们与本义无关。 编码编码也是一个十分常见的概念。比方常常会听到UTF8编码、GBK编码、Base64编码、URL编码、HTML编码、摩斯电码等等一些和编码无关的概念。 生活化地了解编码在理解编码之前,首先通过一个生活化的例子来理解一下“什么是信息,什么是信息的载体”。 全世界,对于“我爱你”这样一句话的表达方式千差万别。口头表白,书面表白,肢体表白,普通话表白,英语表白,音乐表白,绘画表白。甚至有生之年咱们能够脑电波表白。但不管表达方式是如何的,其中蕴含的信息能够是统一的。都是为了传播“我爱你”这样的一个外围价值。 在以上这段表述中,能够将“我爱你”这样的概念了解为“信息”。而各种表达方式了解为这个信息的各种载体。 那么,回到编程的世界中来。计算机中的信息次要的载体是以电磁信号的物理载体存在于计算机世界中。那么如果要将事实世界简单的内容都依附这种载体来表白,就须要进行转化,咱们能够将这种转化了解为编码。联合前文生活化的例子,应用普通话来表白“我爱你”这个信息,就能够了解为应用普通话来编码这个信息。 因而,编码,其能够了解为,采纳一种新的载体来示意前一个载体所表白的信息。 能够套用相似这样一个公式来了解:XX编码,将A编码为B,以实现通过B进行存储或传输传输的目标。 技术相干的编码那么,采纳这样的概念,咱们来了解一下以往见到的各种技术概念: 文本文件编码,将“文本数据”编码为“二进制数据”,以实现通过“二进制数据”进行存储或者传输的目标 文本文件在计算机中,最终的载体是二进制文件的模式存在。早起,因为计算机诞生在美国,文本内容也只蕴含有英文内容。因而过后只有应用ASCII进行编码就能够了。然而起初随着计算机的遍及,须要表白的信息越来越多了。因而诞生了Unicode、GB2312等等编码模式。但不论如何,这些编码其实都是对文本信息的编码模式。 Base64编码,将“二进制数据”编码为“64个可打印字符的组合”,以实现通过“可打印字符的模式”进行存储或者传输的目标 在Web场景中,在有些中央限度了数据传输的形式。例如,在URL,只能传递文本。因而,如果想要传输一组二进制数据。那么能够选用Base64编码,将二进制数据编码为可打印的字符串。这样能力实现URL上二进制数据的传输。 URL编码,将“非数字字母字符”编码为“十六进制转义序列”,以实现通过“十六进制转义序列”进行传输的目标 如果须要在URL中传递中文作为参数,或者须要在URL中传递空格、&、?、=等等特殊符号。这个时候就须要进行URL编码。例如月老板会被编码为%E6%9C%88%E8%80%81%E6%9D%BF。编码的目标HTTP协定的外在要求,通过这种模式,能够浏览器表单数据的打包。 总的来说,通过编码,能够转化信息表白的载体。这样就能够利用新载体带来的益处。这里也有一些生活化的例子: 摩斯电码,将“文本数据”编码为“点横组成的电信号”,以实现通过“电报”进行传输的目标。 例如: -·-- ··- · ·-·· ··- --- ·· ··· - ···· · -- --- ··· - ··-· ·- -- --- ··- ··· -·· ·- ·-·· ·- ---社会主义外围价值观编码,将“文本数据”编码为“社会主义外围价值观组成的字符”,以实现通过“社会主义外围价值观”进行传输的目标。 ...

February 15, 2023 · 1 min · jiezi

关于c#:dotnet-8-preview-1-即将发布

.Net 8 preview 1 行将到来,让咱们来提前看看都要公布什么吧。 .Net 8 preview 1 行将到来.NET 8 的第一个预览版将在几周内公布,微软的 David Ortinau 在斯德哥尔摩举办的一场在线技术流动中说。这个音讯是在.NET Frontend Day 的一个.NET MAUI 的演示中走漏的,这个流动能够在 YouTube 上观看。.NET 8 将在 2023 年 11 月 10 日左右的.NET Conf 2023 流动中公布,.NET GitHub 仓库显示.NET 8 的开发工作曾经实现了 44%。.NET MAUI 和 Blazor 是明天.NET Frontend Day 的重点,GitHub 仓库显示有很多与它们相干的问题,例如“MAUI Android 的 ImageSharp 性能很差”、“Blazor WebAssembly 在低内存的挪动设施上解体”等。Steve Sanderson 在一月份的 YouTube 视频中展现了一个名为 Blazor United 的新我的项目,它是一个原型我的项目,之后会被挪动到了 GitHub 流程中。 可发帖可群聊的技术交换形式曾经上线,欢送通过链接,退出咱们一起探讨。 https://www.newbe.pro/links/将会带来什么?目前已知的包含: BCL: Utility methods for working with randomness. - BCL: 解决随机性的实用办法。CLR AppModel team: NativeAOT size improvements. - CLR AppModel 团队: NativeAOT 大小优化。System.Text.Json Improvements: Missing member handling, Source generator support for required and init properties, Interface hierarchy support, Snake Case and Kebab Case, Add JsonSerializer.MakeReadOnly() and IsReadOnly APIs. - System.Text.Json 改良: 缺失成员解决,源代码生成器反对必须和初始化属性,接口档次反对,蛇形命名和烤串命名,增加 JsonSerializer.MakeReadOnly()和 IsReadOnly APIs。Mono: .NET Hot Reload supports adding instance fields, properties and events - Mono: .NET Hot Reload 反对增加实例字段,属性和事件。WebAssembly: experimental “Webcil” a new container format for .NET assemblies - WebAssembly: 实验性的"Webcil",一种用于.NET 程序集的新容器格局。Mono: Debugging .NET WebAssembly App supports loading symbols from symbol server as configured in Visual Studio - Mono: 调试.NET WebAssembly 应用程序反对从符号服务器加载符号,依照 Visual Studio 的配置。General SIMD improvements - 通用 SIMD 改良。Fundamental PGO improvements - 根本 PGO 改良。Loop Optimizations - 循环优化。JIT Throughput Improvements - JIT 吞吐量改良。.NET Libraries - System.Numerics and System.Runtime.Intrinsics - .NET 库 - System.Numerics 和 System.Runtime.Intrinsics。说点我看得懂的其实很多我也看不懂,找点我看得懂的。 ...

February 14, 2023 · 2 min · jiezi

关于c#:一个容器但是一整个k8s集群

你可能须要一个疾速启动和销毁的 k8s 集群;你可能在资源受限的环境中运行 k8s 集群;你可能是一个齐全的初学者,感觉搭建残缺的 k8s 套件太难。那么这篇短文可能能够帮到你。 各种丐版 k8s 集群你可能见过各种丐版的 k8s 集群部署计划,比方:K3S、K3d、Kind、MicroK8S、Minikube、Docker Desktop。而明天要写的是其中之一:K3d。 为什么抉择 k3d 呢,因为笔者在一个十分非凡的环境中应用 k8s: 这是一个 x86 的 openwrt 软路由零碎,曾经内置了 docker。除了 k3d,其余的计划都因为各种起因而失败了。当然一般的 PC 以上计划都是能够的。而 k3d 简直也是最简略的。笔者打算在这个软路由上装置本人平时要用到的各种中间件,比方 nexus oss、jenkins 等等 。思考到这个环境可能须要做备份和重建,因而须要思考一个疾速启动和销毁的 k8s 集群。后续在加上 argo-cd 等技术,能够实现一个残缺的 k8s 集群的备份和复原。应用 k3d 之前的筹备你须要一个 docker 环境。(必要)开始装置 k3d办法 1,你能够抉择应用官网提供的脚本进行装置: wget -q -O - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash办法 2,你也能够间接下载二进制文件,而后退出到 PATH 即可:https://github.com/k3d-io/k3d... 如果从 github 下载对你的网络来说是一种艰难,你能够抉择 k3d1 或者 FastGithub2 创立一个 k3d.yml 文件k3d.yml 是用户在创立 k3d 集群时应用的配置文件。这是一个范例的配置文件: apiVersion: k3d.io/v1alpha4kind: Simplemetadata: name: k3s-defaultservers: 1 # same as `--servers 1`agents: 2 # same as `--agents 2`image: docker.io/rancher/k3s:v1.25.6-k3s1kubeAPI: # same as `--api-port myhost.my.domain:6445` (where the name would resolve to 127.0.0.1) host: '127.0.0.1' # important for the `server` setting in the kubeconfig # hostIP: "192.168.1.200" # where the Kubernetes API will be listening on hostPort: '6445' # where the Kubernetes API listening port will be mapped to on your host systemports: - port: 80:80 # same as `--port '8080:80@loadbalancer'` nodeFilters: - loadbalanceroptions: k3d: # k3d runtime settings wait: true # wait for cluster to be usable before returining; same as `--wait` (default: true) timeout: '60s' # wait timeout before aborting; same as `--timeout 60s` disableLoadbalancer: false # same as `--no-lb` disableImageVolume: false # same as `--no-image-volume` disableRollback: false # same as `--no-Rollback` loadbalancer: configOverrides: - settings.workerConnections=2048 k3s: # options passed on to K3s itself extraArgs: # additional arguments passed to the `k3s server|agent` command; same as `--k3s-arg` - arg: '--tls-san=127.0.0.1 --tls-san=ks.newbe.io' nodeFilters: - server:* kubeconfig: updateDefaultKubeconfig: true # add new cluster to your default Kubeconfig; same as `--kubeconfig-update-default` (default: true) switchCurrentContext: true # also set current-context to the new cluster's context; same as `--kubeconfig-switch-context` (default: true)registries: # define how registries should be created or used config: | # define contents of the `registries.yaml` file (or reference a file); same as `--registry-config /path/to/config.yaml` mirrors: "docker.io": endpoint: - "https://mirror.ccs.tencentyun.com"创立一个 k3d 集群有了配置文件,当初就能够创立一个 k3d 集群了: ...

February 13, 2023 · 3 min · jiezi

关于c#:C-如何部分加载超大解决方案中的部分项目

在有的特有的我的项目环境下,团队会将所有的我的项目应用同一个解决方案进行治理。这种形式方面了治理,然而却会导致解决方案变得十分宏大,导致加载工夫过长。那么,如何局部加载解决方案中的局部我的项目呢?就让咱们来借用微软退出的slngen 工具来体验一下局部加载解决方案中的局部我的项目吧。 slngen 从根我的项目生成长期解决方案SlnGen 是一个 Visual Studio 解决方案文件生成器。Visual Studio 解决方案对于大型项目树来说通常不能很好地扩大。SlnGen 读取一个给定我的项目的我的项目援用,按需创立一个 Visual Studio 解决方案。例如,你能够针对一个单元测试我的项目运行 SlnGen,并出现一个蕴含单元测试我的项目及其所有我的项目援用的 Visual Studio 解决方案。你也能够针对一个有根的文件夹中的遍历我的项目运行 SlnGen,关上一个蕴含你的我的项目树的那个视图的 Visual Studio 解决方案。 装置 slngendotnet tool install --global Microsoft.VisualStudio.SlnGen.Tool --add-source https://api.nuget.org/v3/index.json --ignore-failed-sources运行以上命令,你就能够在全局装置 slngen 工具了。而后,你就能够在任何中央应用 slngen 命令了。 slngen --help最近咱们正在组织全新的技术交换形式,欢送点击链接莅临指导 https://www.newbe.pro/links/为所有的我的项目引入 Microsoft.VisualStudio.SlnGen在你的我的项目树中,你须要为所有的我的项目引入 Microsoft.VisualStudio.SlnGen 包。能够通过 Directory.Build.props 来轻松实现。 <ItemGroup> <PackageReference Include="Microsoft.VisualStudio.SlnGen" Version="9.5.2" /></ItemGroup>筹备一个长期的测试项目为了不便演示,咱们创立三个我的项目,别离是 slngen-demo、slngen-demo-a、slngen-demo-b。 其中,slngen-demo-a 和 slngen-demo-b 我的项目都援用了 slngen-demo 我的项目。 mkdir slngen-democd slngen-demodotnet new classlib -o slngen-demodotnet new console -o slngen-demo-adotnet new console -o slngen-demo-bcd slngen-demo-adotnet add reference ../slngen-demo/slngen-demo.csprojcd ../slngen-demo-bdotnet add reference ../slngen-demo/slngen-demo.csproj文件夹构造大抵如下: ...

February 10, 2023 · 1 min · jiezi

关于c#:在-AspNet-Core-中什么是认证和授权

认证(Authentication) 和 受权(Authorization)在 Asp.Net core 充当了两个不同的职责。有的老伙计在了解的时候还存在误会。本文咱们将会通过一些简略的例子来阐明这两个概念。 认证(Authentication)辨认你是谁,受权(Authorization)决定你能做什么退出 A 用户当初通过浏览器想要拜访时总的网站,这个时候咱们须要晓得他是谁,也就是认证。如果他是一个普通用户,那么他只能拜访一些公开的页面,如果他是管理员,那么他能够拜访一些管理员的页面。这个时候咱们须要晓得他能做什么,也就是受权。 因而,认证是指辨认用户的身份,而受权是指决定用户能做什么。 特地阐明,辨认你是谁的意思是,你可能被辨认为一个普通用户,也可能被辨认为一个管理员,也可能被辨认为一个游客(匿名用户)。 脱离 Asp.Net Core 认证还有另外一层意思咱们常见的 OAuth2.0 认证、OpenID Connect 认证,账号密码认证,二维码认证等等,这些认证其实是用户与零碎交互而产生凭据的过程。这些凭据能够是一个 token,也能够是一个 cookie,也能够是一个 session。这些凭据都是用来辨认用户身份的。 为了区别这种状况,咱们将前者在本文中称为“登录形式”,后者称为“认证形式”。 而在 Asp.Net Core 中,认证是指申请中的凭据如何被转换为一个 Principal 或者 Identity 对象。所以咱们会见到 Claims-based authentication,也就是基于申明的认证。 所以实际上整个过程,能够了解为:用户通过登录形式登录,如果登录胜利,那么零碎会产生一个凭据,这个凭据回绝与采纳的认证形式无关,而是与 Asp.Net Core 中的认证形式无关。 举一些例子: 用户通过基于账号密码的 OAuth2.0 认证登录,那么零碎会产生一个 JWT token, 而后咱们应用 JWT bearer 认证形式,将这个 token 作为凭据,而后 Asp.Net Core 会将这个 token 转换为一个 Principal 或者 Identity 对象。用户通过手机扫码的形式登录,那么零碎会产生一个 session,而后咱们应用 cookie 认证形式,将这个 session 作为凭据保留在 Cookie中,而后 Asp.Net Core 会将这个 Cookie 转换为一个 Principal 或者 Identity 对象。但其实我也能够这样:用户通过基于账号密码的 OAuth2.0 认证登录,那么零碎会产生一个 JWT token, 而后咱们应用 cookie 认证形式,将这个 token 作为凭据保留在 Cookie中,而后 Asp.Net Core 会将这个 token 转换为一个 Principal 或者 Identity 对象。一些状况那么联合以上状况,咱们来甄别一些词语的意思: ...

February 8, 2023 · 1 min · jiezi

关于c#:如何在-C-项目中链接一个文件夹下的所有文件

在 C# 我的项目中通过链接形式引入文件能够让咱们在我的项目中应用这些文件中的代码。常见的比方链接 AssemblyInfo.cs 文件,这样咱们就能够在我的项目中应用这个文件中的版本号等信息。然而如果咱们想要链接一个文件夹下的所有文件,该怎么做呢?明天咱们就来看看如何在 C# 我的项目中链接一个文件夹下的所有文件。 编辑我的项目文件引入单个文件在我的项目文件中,咱们能够通过 Compile 标签来引入单个文件。比方咱们想要引入 AssemblyInfo.cs 文件,咱们能够这样做: <Project> <ItemGroup> <Compile Include="../Shared/AssemblyInfo.cs"> <Link>Properties/AssemblyInfo.cs</Link> </Compile> </ItemGroup></Project>这样咱们就能够在我的项目中应用 AssemblyInfo.cs 文件中的代码了。 编辑我的项目文件引入文件夹下的所有文件那如果想要引入多个文件,咱们能够应用通配符来引入文件夹下的所有文件。比方咱们想要引入 Shared 文件夹下的所有文件,咱们能够这样做: <Project> <ItemGroup> <Compile Include="..\Shared\**\*.cs"> <Link>Properties/%(Filename)%(Extension)</Link> </Compile> </ItemGroup></Project>这样咱们就能够在我的项目中应用 Shared 文件夹下的所有文件中的代码了。 不过这样会使得所有的文件在我的项目中都会显示在 Properties 文件夹下,这样会让我的项目文件看起来很乱。咱们能够通过批改 Link 标签来批改文件在我的项目中的显示地位。比方咱们想要把 Shared 文件夹下的所有文件都显示在我的项目的根目录下,咱们能够这样做: <Project> <ItemGroup> <Compile Include="..\Shared\**\*.cs"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> </Compile> </ItemGroup></Project>别忘了应用 Directory.Build.props 文件下面的办法都是在我的项目文件中引入文件的,然而如果咱们有很多我的项目,那么咱们就须要在每个我的项目文件中都引入这些文件。这样会让咱们的我的项目文件变得很乱。咱们能够通过应用 Directory.Build.props 文件来解决这个问题。咱们能够在解决文件夹下创立一个 Directory.Build.props 文件,而后在这个文件中引入文件夹下的所有文件。比方咱们想要引入 Shared 文件夹下的所有文件,咱们能够这样做: <Project> <ItemGroup> <Compile Include="..\Shared\**\*.cs"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> </Compile> </ItemGroup></Project>总结通过下面的办法,咱们能够在 C# 我的项目中引入文件夹下的所有文件。这样咱们就能够在我的项目中应用这些文件中的代码了。 参考资料Linking files in a project1Directory.Build.props2感谢您的浏览,如果您感觉本文有用,请点赞、关注和转发;更多精彩内容请关注我的博客 https://www.newbe.pro和https:...。 本文作者: newbe36524本文链接: https://www.newbe.pro/Others/0x017-csharp-how-to-link-all-the-files-in-a-given-folder/版权申明: 本博客所有文章除特地申明外,均采纳 BY-NC-SA 许可协定。转载请注明出处! https://learn.microsoft.com/e... ↩ https://learn.microsoft.com/v... ↩

February 7, 2023 · 1 min · jiezi

关于c#:匿名方法

C# 匿名办法咱们曾经提到过,委托是用于援用与其具备雷同标签的办法。换句话说,您能够应用委托对象调用可由委托援用的办法。 匿名办法(Anonymous methods) 提供了一种传递代码块作为委托参数的技术。匿名办法是没有名称只有主体的办法。 在匿名办法中您不须要指定返回类型,它是从办法主体内的 return 语句推断的。 大题目编写匿名办法的语法匿名办法是通过应用 delegate 关键字创立委托实例来申明的。例如: delegate void NumberChanger(int n); ... NumberChanger nc = delegate(int x) { Console.WriteLine("Anonymous Method: {0}", x); };代码块 Console.WriteLine("Anonymous Method: {0}", x); 是匿名办法的主体。 委托能够通过匿名办法调用,也能够通过命名办法调用,即,通过向委托对象传递办法参数。 留神: 匿名办法的主体前面须要一个 ;。 例如: nc(10);实例上面的实例演示了匿名办法的概念: 实例using System;delegate void NumberChanger(int n);namespace DelegateAppl{ class TestDelegate { static int num = 10; public static void AddNum(int p) { num += p; Console.WriteLine("Named Method: {0}", num); } public static void MultNum(int q) { num *= q; Console.WriteLine("Named Method: {0}", num); } static void Main(string[] args) { // 应用匿名办法创立委托实例 NumberChanger nc = delegate(int x) { Console.WriteLine("Anonymous Method: {0}", x); }; // 应用匿名办法调用委托 nc(10); // 应用命名办法实例化委托 nc = new NumberChanger(AddNum); // 应用命名办法调用委托 nc(5); // 应用另一个命名办法实例化委托 nc = new NumberChanger(MultNum); // 应用命名办法调用委托 nc(2); Console.ReadKey(); } }}当下面的代码被编译和执行时,它会产生下列后果: ...

January 5, 2023 · 1 min · jiezi

关于c#:反射Reflection

反射(Reflection)反射指程序能够拜访、检测和批改它自身状态或行为的一种能力。 程序集蕴含模块,而模块蕴含类型,类型又蕴含成员。反射则提供了封装程序集、模块和类型的对象。 您能够应用反射动静地创立类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。而后,能够调用类型的办法或拜访其字段和属性。 优缺点长处:1、反射进步了程序的灵活性和扩展性。2、升高耦合性,进步自适应能力。3、它容许程序创立和管制任何类的对象,无需提前硬编码指标类。 毛病:1、性能问题:应用反射基本上是一种解释操作,用于字段和办法接入时要远慢于间接代码。因而反射机制次要利用在对灵活性和拓展性要求很高的零碎框架上,一般程序不倡议应用。2、应用反射会含糊程序外部逻辑;程序员心愿在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因此会带来保护的问题,反射代码比相应的间接代码更简单。反射(Reflection)的用处反射(Reflection)有下列用处: 它容许在运行时查看个性(attribute)信息。它容许审查汇合中的各种类型,以及实例化这些类型。它容许提早绑定的办法和属性(property)。它容许在运行时创立新类型,而后应用这些类型执行一些工作。查看元数据咱们曾经在下面的章节中提到过,应用反射(Reflection)能够查看个性(attribute)信息。 System.Reflection 类的 MemberInfo 对象须要被初始化,用于发现与类相干的个性(attribute)。为了做到这点,您能够定义指标类的一个对象,如下: System.Reflection.MemberInfo info = typeof(MyClass);上面的程序演示了这点: 实例using System;[AttributeUsage(AttributeTargets.All)]public class HelpAttribute : System.Attribute{ public readonly string Url; public string Topic // Topic 是一个命名(named)参数 { get { return topic; } set { topic = value; } } public HelpAttribute(string url) // url 是一个定位(positional)参数 { this.Url = url; } private string topic;}[HelpAttribute("Information on the class MyClass")]class MyClass{}namespace AttributeAppl{ class Program { static void Main(string[] args) { System.Reflection.MemberInfo info = typeof(MyClass); object[] attributes = info.GetCustomAttributes(true); for (int i = 0; i < attributes.Length; i++) { System.Console.WriteLine(attributes[i]); } Console.ReadKey(); } }}当下面的代码被编译和执行时,它会显示附加到类 MyClass 上的自定义个性: ...

December 31, 2022 · 3 min · jiezi

关于c#:使用ILSpy反编译C代码

应用ILSpy反编译C#代码 1.点击dll,保留,保留为.csproj文件2.应用visual studio关上.csproj我的项目3.生成即可 碰到的问题:1.把AssemblyInfo.css外面的如下所示删除 [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]2.无奈调试 通过调试->窗口->模块查看 发现该模块被设置为了用户代码:否,符号状态:已跳过加载符号 解决办法:把AssemblyInfo.css里的批改为:而后从新生成即可

November 30, 2022 · 1 min · jiezi

关于c#:ASPNET连接数据库SQL-Server的操作

1.创立好我的项目后在咱们的Web.config外面连贯SQL Server数据库 2.写入代码<appSettings> <add key="conStr" value="Data Source=localhost;Initial Catalog=s;Integrated Security=True;" /> </appSettings>conStr是字段名字,前面连贯须要,localhost是本地地址的意思,s是数据库中的表名。 3.选中shujuku练习右击,抉择增加,而后在抉择Web窗体 4.创立好的Web窗体如下窗体中的代码:就增加了一个显示控件cs文件代码如下: using System;using System.Configuration;using System.Data;using System.Data.SqlClient;namespace shujuiku练习{ public partial class WebForm1 : System.Web.UI.Page { private static string constr;//这里就是咱们定义数据库的字段constr private static SqlConnection conn;//创立数据库连贯字段 protected void Page_Load(object sender, EventArgs e) { constr = ConfigurationManager.AppSettings["conStr"].ToString(); conn = new SqlConnection(constr);//创立数据库连贯实例化对象 DataSet ds = new DataSet();// 实例化DataSet类型的对象ds SqlDataAdapter s = new SqlDataAdapter("select * from SysUser;", conn);//实例化DataAdapter对象 s.Fill(ds);//填充ds GridView1.DataSource=ds;//将该数据显示在GridView1控件上 GridView1.DataBind(); } }}5.网页效果图和数据库的表:

November 7, 2022 · 1 min · jiezi

关于c#:委托与事件的定义与用法

1.委托1.1定义及应用委托是一种动静调用办法的类型,它与类、接口和数组雷同属于援用型。 注意事项:委托实际上定义了一种办法的模板,只有返回值类型和形参列表与该模板统一,就都可用该委托类型进行实例化。 委托对象实质上代表了办法的援用。在.NET Framework 中,委托具备以下特点。(1)委托相似于 C++函数指针,但与指针不同的是,委托是齐全面向对象的、平安的数据类型。(2)委托容许将办法作为参数进行传递。(3)委托可用于定义回调办法。(4)委托能够把多个办法连贯在一起,这样在触发事件时,可同时启动多个事件处理程序。 委托(delegate)申明的个别模式:[拜访修饰符] delegate 返回值类型 委托名( [参数列表] );如:public delegate int Do( int x);下面的语句申明了一个公开的名为“Do”的委托,该委托返回值类型为整型。例如:public delegate void wt(int x);定义一个没有返回值、带有整型参数的x的一个名叫wt的委托。 具体怎么应用接下来看看代码示例: namespace C练习 { public delegate void wt(int x); class Program { public static void Add(int x) //定义了一个静态方法Add,留神该办法的返回值类型和参数与委托的雷同 { Console.WriteLine(x+x); //输入x+x的值 } public static void Cheng(int x)//同上 { Console.WriteLine(x*x); } static void Main(string[] args) { wt j = Add; //用委托定义j并调用Add办法 j += Cheng; //+代表在j的根底上增加Cheng办法 j -= Cheng;//-代表在j的根底上移除Cheng办法 j(3); } }}那么输入的后果就为:6 ...

October 30, 2022 · 1 min · jiezi

关于c#:C隐藏基类成员base用法

代码如下:class Program { public class Student//定义一个学生类,其中字段有姓名、年龄、学号 { private string Name; private string Age; private int Id; public Student(string name,string age,int id)//创立学生类的构造函数 { Name = name; Age = age; Id = id; } public void sc()//定义一个输入办法sc,别离输入姓名,年龄,学号信息 { Console.WriteLine("姓名:{0}", Name); Console.WriteLine("年龄:{0}", Age); Console.WriteLine("学号:{0}", Id); } } public class e : Student//定义一个新类e来根底学生类,换个说法就是e是学生类的子类 { private string department;//定义两个字段业余和性别 private string sex; public e(string name, string age, int id, string d,string s) : base(name, age, id) { department = d; sex = s; } new public void sc()//应用new修饰符清晰的表明了派生类暗藏了基类,如果不加new,编译会有正告 { base.sc();//调用基类的构造函数 Console.WriteLine("业余:{0}", department); Console.WriteLine("性别:{0}", sex); } } static void Main(string[] args) { e s1 = new e("张三", "22", 12, "软件工程", "男");//实例化派生类对象为s1,写入相应信息。 s1.sc(); }}编译后果如下: ...

October 29, 2022 · 1 min · jiezi

关于c#:C什么是面向对象类

面向对象本质就是对事实世界的对象进行建模操作。 1.首先什么是对象1.其实随处可见的事物就是一个对象,对象是事物存在的实体,比方人类,计算机等等。其实咱们也能够了解为对象=行为+字段。 2.什么是类类就是一组具备雷同属性和行为的对象的形象,也能够了解为类是一组具备雷同属性和行为的对象的汇合,为该类的所有对象提供对立的形象形容。类的申明个别模式如下: [拜访修饰符] class 类名 [:基类] { 类的成员; }其中,拜访修饰符用来限度类的作用范畴或拜访级别。常见拜访修饰符有:public、private、protected等。如下图例子所示:这里我定义了一个学生类,其中字段包含学号、姓名,一个性别的属性,还有一个办法。那么有人就会纳闷什么是字段、属性和办法? 2.1字段字段示意类的成员变量,字段的值代表某个对象的数据状态。不同的对象,数据状态不同,意味着各字段的值也不同。申明字段的办法与定义一般变量的办法雷同,其个别格局如下:[拜访修饰符] 数据类型 字段名;其中,拜访修饰符用来管制字段的拜访级别,可省略。就如下面的图所示: public string name; 2.2属性字段和常量形容了类的数据,当这些数据容许外界拜访时,能够应用拜访修饰符public,不容许外界拜访时,能够应用private或protected等。但当咱们心愿某些字段只读拜访(如上例中的PI);或者只写访问;或者可读可写访问时,须要应用属性。public、private等拜访修饰符管制成员能不能被拜访;属性管制以何种形式拜访(只读、只写或可读写)。类的属性定义个别模式如下: [拜访修饰符] 数据类型 属性名{ get { //获取属性的代码,用return 返回值 } set { //设置属性的代码,用value赋值 }}拜访修饰符管制成员能不能被拜访;属性管制以何种形式拜访(只读、只写或可读写)。 2.3办法申明办法的个别模式如下: [拜访修饰符] 返回值类型 办法名 ([参数列表]) { 语句; …… [return 返回值;] }如上图所示,我定义了一个办法run(),目标输入跑步这条信息。 综上所述,一个类就定义好了,如果感觉还不错点个赞呦!

October 28, 2022 · 1 min · jiezi

关于c#:openKylin出品-COSCon22-开源操作系统论坛快来看看吧

业界具备宽泛影响力的开源年度盛会2022第七届中国开源年会(COSCon22)将于10月29日-30日由开源社举办。往年,咱们的主题是: Open the World !咱们喜爱 Open 胜过 Close咱们喜爱 Connection 胜过 Broken咱们喜爱 Public Good 胜过 Bad News咱们心愿能以开源的技术、开源的形式、开源的力量,为改善这个世界做出一点奉献。线上共设有1个主论坛和16个分论坛,其中【开源操作系统论坛】由openKylin技术负责人余杰和西安邮电大学传授陈莉君联结出品。目前,残缺论坛议程已出,快来一起看看吧~01论坛介绍开源曾经被写入国家十四五布局,目前国内外开源操作系统倒退迅速,操作系统开源社区建设热火朝天。本次论坛拟邀请国内外开源操作系统的开发者和爱好者独特分享与探讨开源操作系统的研制停顿、痛点痒点和将来布局,一起畅想开源操作系统的美妙今天。直播观看地址:http://segmentfault.com/area/...本次大会的线上互动群(COSCon'22 @开源人团圆)也如约而至。退出社群,理解大会一手信息,精彩周边拿不停!出品丨COSCon'22组委会编辑丨王梦玉设计丨苏子馨 王梦玉 朱亿钦openKylin(凋谢麒麟)社区旨在以“共创”为外围,在开源、被迫、平等、合作的根底上,通过开源、凋谢的形式与企业构建合作伙伴生态体系,独特打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态凋敝倒退。社区首批理事成员单位包含麒麟软件、普华根底软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、元心科技、中国电科32所、技德零碎、北京麟卓、先进操作系统翻新核心等13家产业同仁和行业机构。

October 26, 2022 · 1 min · jiezi

关于c#:NET候选版本2发布

本文作者为Jon Douglas、Jeremy Likness 和 Angelos Petropoulos 明天,咱们发表推出 .NET 7 Release Candidate 2。这是 .NET 7 的最终候选版本(RC),并在生产环境中失去反对。 您能够下载实用于 Windows、macOS 和 Linux 的 .NET 7 Release Candidate 2。  安装程序和二进制文件容器图像Linux 软件包发行阐明已知的问题GitHub 问题跟踪器.NET 7 Release Candidate 2 已通过 Visual Studio 17.4 Preview 3 测试。如果您想在 Visual Studio 系列产品中试用 .NET 7,咱们建议您应用预览通道构建。如果您应用的是 macOS,咱们倡议应用最新的 Visual Studio 2022 for Mac 预览版。 不要遗记 .NET Conf 2022。在 2022 年 11 月 8 日至 10 日与咱们一起庆贺 .NET 7 的公布! 在本博客中,咱们将重点介绍 .NET 7 的外围主题,并为您提供深刻理解细节的资源。 ...

October 18, 2022 · 3 min · jiezi

关于c#:80c-报错-SystemSecuritySecurityException-未找到源无法启动计算机上的服务

利用场景: 利用c#创立windows服务,c#程序默认没有管理员的权限。 服务装置尽管胜利, 但在启动时:提醒: 无奈启动计算机“.”上的服务 看日志: System.Security.SecurityException 未找到源。 配置下以管理员身份运行。 配置过程: (1)在要编译的我的项目上右击抉择【属性】而后抉择【安全性】再勾选上【启用ClickOnce平安设置】,此时会在解决方案资源管理器的Properties中生成app.manifest文件。 (2)双击关上生成的app.manifest文件,找到如下代码: <requestedExecutionLevel level="asInvoker" uiAccess="false" /> 将其批改为: <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />(3)而后在【安全性】中去掉对【启用ClickOnce平安设置】的勾选,全副保留后从新编译就能够了。 参考起源: https://blog.csdn.net/songyi160/article/details/49926433

October 15, 2022 · 1 min · jiezi

关于c#:79C-在创建窗口句柄之前不能在控件上调用-Invoke-或-BeginInvoke错误的解决办法

会呈现这个谬误的可能起因为:窗体敞开了,但还有线程没执行完,且该线程有在操作窗体的内容: if (_lik启动工作.IsHandleCreated) { _lik启动工作.Invoke(new Action(() => { if (rs.Exists == true) { _lik启动工作.Enabled = true; if (rs.status == ServiceControllerStatus.Running) { _lik启动工作.Text = "进行工作(已启动)"; } else { _lik启动工作.Text = "启动工作(未启动)"; } _lik装置与卸载服务.Text = "卸载服务"; } else { _lik启动工作.Text = "启动工作(服务不存在)"; _lik启动工作.Enabled = false; _lik装置与卸载服务.Text = "装置服务"; } })); }若没有加:_lik启动工作.IsHandleCreated 这个if判断,间接执行,就会报错。 _lik启动工作 是窗体的link控件。

October 14, 2022 · 1 min · jiezi

关于c#:78c-各种路径AppDomainCurrentDomainBaseDirectory等

控制台程序: static void Main(string[] args) { // 获取程序的基目录。 string p1 = System.AppDomain.CurrentDomain.BaseDirectory; Console.WriteLine("p1=" + p1); // 获取模块的残缺门路,蕴含文件名 string p2 = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; Console.WriteLine("p2=" + p2); // 获取和设置当前目录(该过程从中启动的目录)的齐全限定目录。 string p3 = System.Environment.CurrentDirectory; Console.WriteLine("p3=" + p3); // 获取应用程序的当前工作目录,留神工作目录是能够扭转的,而不限定在程序所在目录。 string p4 = System.IO.Directory.GetCurrentDirectory(); Console.WriteLine("p4=" + p4); // 获取和设置包含该应用程序的目录的名称。 string p5 = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; Console.WriteLine("p5=" + p5); // 获取启动了应用程序的可执行文件的门路。 /*string p6 = System.Windows.Forms.Application.StartupPath; Console.WriteLine("p6=" + p6); // 获取启动了应用程序的可执行文件的门路及文件名 string p7 = System.Windows.Forms.Application.ExecutablePath; Console.WriteLine("p7=" + p7);*/ Console.ReadLine(); }后果为: ...

October 14, 2022 · 1 min · jiezi

关于c#:C-编写的-64位操作系统-MOOS

MOOS ( My Own Operating System ) 是一个应用 .NET Native AOT 技术编译的C# 64位操作系统。我的项目地址:https://github.com/nifanfa/MOOS。 微软MVP实验室研究员 编译对于编译 MOOS 的信息,请浏览编译维基页面:https://github.com/nifanfa/MO... 编译要求VMware Workstation Playerhttps://www.vmware.com/produc...Visual studio 2022https://visualstudio.microsof...QEMUhttps://www.qemu.org/download 或 VMWare ( 留神,VMware 不反对 USB 键鼠模仿。)Windows 10-11 x64或x868GB Ram 特色 微软最有价值专家(MVP) 微软最有价值专家是微软公司授予第三方技术专业人士的一个寰球奖项。29年来,世界各地的技术社区领导者,因其在线上和线下的技术社区中分享专业知识和教训而取得此奖项。 MVP是通过严格筛选的专家团队,他们代表着技术最精湛且最具智慧的人,是对社区投入极大的激情并乐于助人的专家。MVP致力于通过演讲、论坛问答、创立网站、撰写博客、分享视频、开源我的项目、组织会议等形式来帮忙别人,并最大水平地帮忙微软技术社区用户应用 Microsoft 技术。 更多详情请登录官方网站:https://mvp.microsoft.com/zh-cn 点击理解更多的C# 编写的 64位操作系统 - MOOS

October 12, 2022 · 1 min · jiezi

关于c#:71c-创建logtxt文件并写日志

private void WriteLog(string content) { try { string filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log/log_win.txt"); content = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + content; bool append = true; if (System.IO.File.Exists(filePath) == true) { var fileinfo = new System.IO.FileInfo(filePath); if (fileinfo.Length >= 1024 * 1024 * 10) //如果大于等于1M(1024B*1024KB),则重写日志。 { append = false; } } var logFileStream = new System.IO.StreamWriter(filePath, append, System.Text.Encoding.UTF8); logFileStream.WriteLine(content); logFileStream.Flush(); logFileStream.Close(); } catch(Exception e) { } }

October 11, 2022 · 1 min · jiezi

关于c#:70c-定时器-timer

private void GenTimer() { var timer = new System.Timers.Timer(1000*60*10);//10分钟 timer.AutoReset = true;//AutoReset 属性为 true 时,每隔指定工夫循环一次;如果为 false,则只执行一次。 timer.Enabled = true; timer.Elapsed += new System.Timers.ElapsedEventHandler(RefreshLoadedGsmPort); } private void RefreshAllGsmPort(object sender, EventArgs e) { InitAllGsmPort(); Console.WriteLine("RefreshAllGsmPort..."); }

October 11, 2022 · 1 min · jiezi

关于c#:开源福利-FreeRedis-历时两年正式发布-v10-CNET-Redis-Client

前言.NET 下 RedisClient SDK 抉择挺多,国人罕用收费的有 StackExchange.Redis/CSRedis/Newlife.Redis,免费的有 ServiceStack.Redis。 如果你是 CSRedis 或 ServiceStack.Redis 粉,那么肯定要不要错过关注 FreeRedis,它们的 API 十分类似,办法名、参数与 redis.io 官网命令文档保持一致,防止了二次转换的了解老本。 redis 命令可是有靠近300个呢~~~ 提醒:CSRedisCore 与 FreeRedis 是同一个作者,后者是基于 redis6.0 个性从新打造,解决了 CSRedisCore 的一些老问题,扩展性更强。 开源理念FreeRedis 的命名来自,“自在”、“收费”,它和名字与 FreeSql 是一个理念,繁难是他们统一的追寻方向,最低可反对 .NET Framework 4.0 运行环境,反对到 Redis-server 8.0(超时空版本)。 开源地址:https://github.com/2881099/FreeRedis FreeRedis 以最宽松的开源协定 MIT 开源,从第一个版本 v0.0.1 公布至今已有 22个月,工夫验证了其可靠性,是时候正式公布 v1.0 版本公开给大家,大家做 .neter 不容易,多一个抉择多一条路。 因为之前异步办法的优化始终未凋谢,v1.0 正式凋谢异步办法FreeRedis 整个源码是零依赖,应用它只会在 bin 目录产生一个 FreeRedis.dll,十分的轻量级,并且其性能十分弱小: <h1> FreeRedis </h1> 基于 .NET 的 Redis 客户端,反对 .NET Core 2.1+、.NET Framework 4.0+ 以及 Xamarin。 ...

September 18, 2022 · 2 min · jiezi

关于c#:winform数据导出CSV

winform数据导出CSV.csv是一种逗号分隔值文件格式,其文件以纯文本模式存储表格数据(数字和文本)。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。通常都是纯文本文件。/// <summary>/// 数据导出/// </summary>/// <param name="dataGridView"></param>/// <returns></returns>private bool dataGridViewToCSV(DataGridView dataGridView){ if(dataGridView.Rows.Count == 0) { MessageBox.Show("没有数据可导出!", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "CSV files (*.csv)|*.csv"; saveFileDialog.FilterIndex = 0; saveFileDialog.RestoreDirectory = true; saveFileDialog.CreatePrompt = true; saveFileDialog.FileName = null; saveFileDialog.Title = "保留"; DateTime now = DateTime.Now; saveFileDialog.FileName = now.Year.ToString().PadLeft(2) + now.Month.ToString().PadLeft(2, '0') + now.Day.ToString().PadLeft(2, '0') + "-" + now.Hour.ToString().PadLeft(2, '0') + now.Minute.ToString().PadLeft(2, '0') + now.Second.ToString().PadLeft(2, '0'); if(saveFileDialog.ShowDialog() == DialogResult.OK) { Stream stream = saveFileDialog.OpenFile(); StreamWriter sw = new StreamWriter(stream, System.Text.Encoding.GetEncoding(-0)); string strLine = ""; try { //表头 for(int i = 0; i < dataGridView.ColumnCount; i++) { if(i > 0) strLine += ","; strLine += dataGridView.Columns[i].HeaderText; } strLine.Remove(strLine.Length - 1); sw.WriteLine(strLine); strLine = ""; //表的内容 for(int j = 0; j < dataGridView.Rows.Count; j++) { strLine = ""; int colCount = dataGridView.Columns.Count; for(int k = 0; k < colCount; k++) { if(k > 0 && k < colCount) strLine += ","; if(dataGridView.Rows[j].Cells[k].Value == null) strLine += ""; else { string cell = dataGridView.Rows[j].Cells[k].Value.ToString().Trim(); //避免外面含有特殊符号 cell = cell.Replace("\"", "\"\""); cell = "\"" + cell + "\""; strLine += cell; } } sw.WriteLine(strLine); } sw.Close(); stream.Close(); MessageBox.Show("数据被导出到:" + saveFileDialog.FileName.ToString(), "导出结束", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch(Exception ex) { MessageBox.Show(ex.Message, "导出谬误", MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } } return true;}

September 5, 2022 · 1 min · jiezi

关于c#:dataGridView读写文本

dataGridViewDataGridView控件是数据表格控件,属于很罕用的控件。 winform DataGridView 属性阐明① 获得或者批改以后单元格的内容 ② 设定单元格只读 ③ 不显示最上面的新行 ④ 判断新增行 ⑤ 行的用户删除操作的自定义 ⑥ 行、列的暗藏和删除 ⑦ 禁止列或者行的Resize ⑧ 列宽和行高以及列头的高度和行头的宽度的主动调整 ⑨ 解冻列或行 ⑩ 列程序的调整 ⑪ 行头列头的单元格⑫ 剪切板的操作 ⑬ 单元格的ToolTip的设置 ⑭ 右键菜单(ContextMenuStrip)的设置 ⑮ 单元格的边框、 网格线款式的设定 ⑯ 单元格示意值的设定 ⑰ 用户输出时,单元格输出值的设定 ⑱ 设定新加行的默认值 constant con = new constant();//读取private void loadlistbox2(){ dataGridView1.ColumnCount = 1; string z; if(File.Exists(".//allitems.txt")) { FileStream fs = new FileStream(".//allitems.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read); StreamReader sr = new StreamReader(fs, System.Text.Encoding.GetEncoding("utf-8")); try { while(true) { z = sr.ReadLine(); if(z == null) break; dataGridView1.Rows.Add(z); } } finally { sr.Close(); fs.Dispose(); fs.Close(); } }}string st = "";//写入private void savetestitem(){ // dataGridView1.ColumnCount = 1; if(File.Exists(".//allitems.txt")) { FileStream fs = new FileStream(".//allitems.txt", System.IO.FileMode.Open, System.IO.FileAccess.Write); StreamWriter sr = new StreamWriter(fs, System.Text.Encoding.GetEncoding("utf-8")); try { for(int i = 0; i < 22; i++) { for(int j = 0; j < 1; j++) { st = st + dataGridView1.Rows[i].Cells[j].Value; } sr.WriteLine(st); st = ""; //for (int i = 0; i < dataGridView1.Rows.Count; i++) //{ // sr.WriteLine(dataGridView1.Rows[i].Cells); // } } } finally { sr.Close(); fs.Dispose(); fs.Close(); } }}

September 5, 2022 · 1 min · jiezi

关于c#:NPinyin-不支持中英混合转换怎么破

最近在我的项目中用到汉字转拼音的需要,用的是 NPinyin 来实现的,然而在应用的过程中呈现了与预期不符的状况。 咱们先来看看失常应用: string str = NPinyin.Pinyin.GetPinyin("小黄本黄");Console.WriteLine(str);输入为 xiao huang ben huang显然,这是合乎预期的,但如果咱们在调用这个转换方法前,不晓得以后字符串是中文还是拼音,那咱们预期是不是会冀望对拼音局部不做扭转呢?但实际上不是的: string str = NPinyin.Pinyin.GetPinyin("xiao huang ben huang");Console.WriteLine(str);输入为 x i a o h u a n g b e n h u a n g它对每个英文字符也做了转换,导致每个字符前面多出了一个空格。 如果咱们做以下调整,就能够返回咱们预期的后果啦 public static string GetPinyin(string str){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < str.Length; i++) { if (str[i] > 127) { string pinyin = Pinyin.GetPinyin(str[i]); sb.Append(pinyin); // 如果是最初一位,就不必追加空格 if (i == str.Length - 1) continue; // 如果不是最初一位,但下一位是符号,也不必追加空格 if (char.IsPunctuation(str[i+1])) continue; sb.Append(" "); continue; } sb.Append(str[i]); } return sb.ToString();}咱们测试一下 ...

August 31, 2022 · 1 min · jiezi

关于c#:重温-C-Lambda-表达式

尽管从事 .Net 开发有较长一段时间了,但对一些基础知识把握得不是很好,近期换了工作了,看到代码中的一些 Action 和 Func<> 的用法,于是来补一下根底。 首先说一下几个规定,就能很好了解了: Lambda 运算符,=> 读做 "goes to"=> 左侧为参数,右侧为表达式或语句块,如 (a,b) => a+b,示意 a,b 为入参,返回值为 a+b=> 左边有 {} 时,为语句块,无 {} 时,为表达式Action 无返回值,Func<> 有返回值;即 Action<in T1,in T2> 中,T1 和 T2 都为入参,而 Func<in T1,in T2,out T3> 中,T1 和 T2 为入参,T3 为返回值(最初一个为返回值)。咱们举个例子吧 表达式// return min valueFunc<int,int,int> Min = (a,b) => a < b ? a : b;int x = Min(1,2);Console.WriteLine(x);// 1语句块Func<int,int,int> Min = (a,b) =>{ if (a < b) return a; return b;};int x = Min(1,2);Console.WriteLine(x);// 1再举一个 Action 的例子吧 ...

August 28, 2022 · 1 min · jiezi

关于c#:反射

public static T DeepCopyByReflect<T>(T obj) { //如果是字符串或值类型则间接返回 if (obj is string || obj.GetType().IsValueType) return obj; object retval = Activator.CreateInstance(obj.GetType()); FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); foreach (FieldInfo field in fields) { try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); } catch { } } return (T)retval; }

August 26, 2022 · 1 min · jiezi

关于c#:树形结构数据获取

记录代码如下: /// <summary> /// 返回树形下拉框 菜单数据 /// </summary> /// <returns></returns> [HttpGet] public ActionResult GetTreeList(int hosid=0,int pid=0) { var hoslist = yqBll.GetListall(); var dptmodel = departmentBLL.GetModelList(" F_State=1"); dptmodel.Sort((x, y) => x.F_Sort ?? 0 - y.F_Sort ?? 0);//排序 var treeList = new List<TreeModel>(); if (hoslist.Count > 0) { foreach (var hositem in hoslist) { TreeModel treeModel = new TreeModel(); treeModel.id = hositem.T_Woid.ToString(); treeModel.IconCls = ""; treeModel.text = hositem.T_Woname; treeModel.parentid = "-1"; treeModel.TypeId = 1; treeModel.children = TreeRecursion(dptmodel, "0", hositem.T_Woid); treeList.Add(treeModel); //var dptlist = dptmodel.Where(p => p.F_ParentId == 0 && p.T_Woid == hositem.T_Woid).ToList(); } } //return Content(treeList.ToJson()); return Success("获取菜单树胜利", treeList); } private List<TreeModel> TreeRecursion(List<Model.T_Sys_Department> data, string parentId = "0", int hosid = 0) { List<Model.T_Sys_Department> item = null; List<TreeModel> newList = new List<TreeModel>(); //if (parentId != "0") //{ if (hosid != 0) { item = data.FindAll(t => t.F_ParentId.ToString() == parentId && t.T_Woid == hosid);//data倡议在调用此扩大办法前曾经排序过 } else { item = data.FindAll(t => t.F_ParentId.ToString() == parentId);//data倡议在调用此扩大办法前曾经排序过 } if (item.Count > 0) { foreach (Model.T_Sys_Department entity in item) { TreeModel treeModel = new TreeModel(); treeModel.id = entity.F_DeptId.ToString(); treeModel.IconCls = ""; treeModel.text = entity.F_DeptName; treeModel.parentid = entity.F_ParentId.ToString(); treeModel.TypeId = 2; treeModel.children = TreeRecursion(item, entity.F_DeptId.ToString()); newList.Add(treeModel); } } //} return newList; }

August 11, 2022 · 1 min · jiezi

关于c#:C语言经典题刷题打卡日记

温故而知新,最近几天从新回顾下这个月刷过的c语言题目 1. 三个数由小到大排序输出任意3个整数,编程实现对这3个整数进行由小到大排序井将排序后的结果显示在屏幕上 #include <stdio.h>#include <stdlib.h>int main(){ int a, b, c, t; printf("请任意输出三个数(空格分隔):\n"); scanf("%d %d %d", &a, &b, &c); if (a < b) { t = a; a = b; b = t; } else if (a < c) { t = a; a = c; c = t; } else if (b < c) { t = b; b = c; c = t; } printf("从大到小排列为:%d %d %d\n", a, b, c); system("pause"); return 0;}2. a²+b²要求输出整数a和 b, 若a²+b²的后果大与100, 则输入a²+b²的值,否则输入 a+b 的后果 ...

July 31, 2022 · 2 min · jiezi