24. Attributes

本文介绍了C#中属性的概念及其使用方式。属性允许程序员为程序元素定义新的声明信息,并能在运行时环境中检索这些信息。文章还举例说明了如何通过自定义属性来增强程序的描述性和功能性。
[Note: Much of the C# language enables the programmer to specify declarative
information about the
entities defined in the program. For example, the accessibility of a method
in a class is specified by
decorating it with the method-modifiers public, protected, internal, and
private. end note]
C# enables programmers to invent new kinds of declarative information,
called attributes. Programmers can
then attach attributes to various program entities, and retrieve attribute
information in a run-time
environment. [Note: For instance, a framework might define a HelpAttribute
attribute that can be placed
on certain program elements (such as classes and methods) to provide a
mapping from those program
elements to their documentation. end note]
Attributes are defined through the declaration of attribute classes (§24.1),
which may have positional and
named parameters (§24.1.2). Attributes are attached to entities in a C#
program using attribute specifications
(§24.2), and can be retrieved at run-time as attribute instances (§24.3). 
 
解析如下代码: import BaseLayerViewGL2D from "@arcgis/core/views/2d/layers/BaseLayerViewGL2D.js"; import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js"; import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js"; const CustomLayerView2D = BaseLayerViewGL2D.createSubclass({ // Locations of the two vertex attributes that we use. They // will be bound to the shader program before linking. aPosition: 0, aOffset: 1, aTexcoord: 2, aDistance: 3, aUpright: 4, constructor() { // Geometrical transformations that must be recomputed // from scratch at every frame. this.transform = mat3.create(); this.rotation = mat3.create(); this.translationToCenter = vec2.create(); this.screenTranslation = vec2.create(); this.display = mat3.create(); // Whether the vertex and index buffers need to be updated // due to a change in the layer data. this.needsUpdate = false; }, // Called once a custom layer is added to the map.layers collection and this layer view is instantiated. attach() { const gl = this.context; // We listen for changes to the graphics collection of the layer // and trigger the generation of new frames. A frame rendered while // `needsUpdate` is true may cause an update of the vertex and // index buffers. const requestUpdate = () => { // Tessellate graphics. this.promises = []; this.layer.graphics.forEach(this.processGraphic.bind(this)); Promise.all(this.promises).then((meshes) => { this.meshes = meshes; this.needsUpdate = true; this.requestRender(); }); }; this.watcher = reactiveUtils.watch( () => this.layer.graphics, requestUpdate, { initial: true } ); // Define and compile shaders. const vertexSource = ` precision highp float; uniform mat3 u_transform; uniform mat3 u_rotation; uniform mat3 u_display; attribute vec2 a_position; attribute vec2 a_offset; attribute vec2 a_texcoord; attribute float a_distance; attribute float a_upright; varying vec2 v_texcoord; void main(void) { vec3 transformedOffset = mix(u_rotation * vec3(a_offset, 0.0), vec3(a_offset, 0.0), a_upright); gl_Position.xy = (u_display * (u_transform * vec3(a_position, 1.0) + transformedOffset)).xy; gl_Position.zw = vec2(0.0, 1.0); v_texcoord = a_texcoord; }`; const fragmentSource = ` precision highp float; varying vec2 v_texcoord; void main(void) { gl_FragColor = vec4(v_texcoord, 0.9, 0.5); }`; const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, vertexSource); gl.compileShader(vertexShader); const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, fragmentSource); gl.compileShader(fragmentShader); // Create the shader program. this.program = gl.createProgram(); gl.attachShader(this.program, vertexShader); gl.attachShader(this.program, fragmentShader); // Bind attributes. gl.bindAttribLocation(this.program, this.aPosition, "a_position"); gl.bindAttribLocation(this.program, this.aOffset, "a_offset"); gl.bindAttribLocation(this.program, this.aTexcoord, "a_texcoord"); gl.bindAttribLocation(this.program, this.aDistance, "a_distance"); gl.bindAttribLocation(this.program, this.aUpright, "a_upright"); // Link. gl.linkProgram(this.program); // Shader objects are not needed anymore. gl.deleteShader(vertexShader); gl.deleteShader(fragmentShader); // Retrieve uniform locations once and for all. this.uTransform = gl.getUniformLocation( this.program, "u_transform" ); this.uRotation = gl.getUniformLocation( this.program, "u_rotation" ); this.uDisplay = gl.getUniformLocation(this.program, "u_display"); // Create the vertex and index buffer. They are initially empty. We need to track the // size of the index buffer because we use indexed drawing. this.vertexBuffer = gl.createBuffer(); this.indexBuffer = gl.createBuffer(); // Number of indices in the index buffer. this.indexBufferSize = 0; // When certain conditions occur, we update the buffers and re-compute and re-encode // all the attributes. When buffer update occurs, we also take note of the current center // of the view state, and we reset a vector called `translationToCenter` to [0, 0], meaning that the // current center is the same as it was when the attributes were recomputed. this.centerAtLastUpdate = vec2.fromValues( this.view.state.center[0], this.view.state.center[1] ); }, // Called once a custom layer is removed from the map.layers collection and this layer view is destroyed. detach() { // Stop watching the `layer.graphics` collection. this.watcher.remove(); const gl = this.context; // Delete buffers and programs. gl.deleteBuffer(this.vertexBuffer); gl.deleteBuffer(this.indexBuffer); gl.deleteProgram(this.program); }, // Called every time a frame is rendered. render(renderParameters) { const gl = renderParameters.context; const state = renderParameters.state; // Update vertex positions. This may trigger an update of // the vertex coordinates contained in the vertex buffer. // There are three kinds of updates: // - Modification of the layer.graphics collection ==> Buffer update // - The view state becomes non-stationary ==> Only view update, no buffer update // - The view state becomes stationary ==> Buffer update this.updatePositions(renderParameters); // If there is nothing to render we return. if (this.indexBufferSize === 0) { return; } // Update view `transform` matrix; it converts from map units to pixels. mat3.identity(this.transform); this.screenTranslation[0] = (state.pixelRatio * state.size[0]) / 2; this.screenTranslation[1] = (state.pixelRatio * state.size[1]) / 2; mat3.translate( this.transform, this.transform, this.screenTranslation ); mat3.rotate( this.transform, this.transform, (Math.PI * state.rotation) / 180 ); mat3.scale(this.transform, this.transform, [ state.pixelRatio / state.resolution, -state.pixelRatio / state.resolution ]); mat3.translate( this.transform, this.transform, this.translationToCenter ); // Update view `rotate` matrix; it is the rotation component of the full `transform` matrix. mat3.identity(this.rotation); mat3.rotate( this.rotation, this.rotation, (Math.PI * state.rotation) / 180 ); // Update view `display` matrix; it converts from pixels to normalized device coordinates. mat3.identity(this.display); mat3.translate(this.display, this.display, [-1, 1]); mat3.scale(this.display, this.display, [ 2 / (state.pixelRatio * state.size[0]), -2 / (state.pixelRatio * state.size[1]) ]); // Draw. gl.useProgram(this.program); gl.uniformMatrix3fv(this.uTransform, false, this.transform); gl.uniformMatrix3fv(this.uRotation, false, this.rotation); gl.uniformMatrix3fv(this.uDisplay, false, this.display); gl.uniform1f(this.uCurrentTime, performance.now() / 1000.0); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.enableVertexAttribArray(this.aPosition); gl.enableVertexAttribArray(this.aOffset); gl.enableVertexAttribArray(this.aTexcoord); gl.enableVertexAttribArray(this.aDistance); gl.enableVertexAttribArray(this.aUpright); gl.vertexAttribPointer(this.aPosition, 2, gl.FLOAT, false, 32, 0); gl.vertexAttribPointer(this.aOffset, 2, gl.FLOAT, false, 32, 8); gl.vertexAttribPointer(this.aTexcoord, 2, gl.FLOAT, false, 32, 16); gl.vertexAttribPointer(this.aDistance, 1, gl.FLOAT, false, 32, 24); gl.vertexAttribPointer(this.aUpright, 1, gl.FLOAT, false, 32, 28); gl.enable(gl.BLEND); gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); gl.disable(gl.CULL_FACE); gl.drawElements( gl.TRIANGLES, this.indexBufferSize, gl.UNSIGNED_SHORT, 0 ); // Request new render because markers are animated. this.requestRender(); }, processGraphic(g) { switch (g.geometry.type) { case "extent": this.promises.push( this.tessellateExtent(g.geometry).then( (mesh) => { return { mesh: mesh, attributes: g.attributes, symbol: g.symbol }; } ) ); break; case "point": this.promises.push( this.tessellatePoint(g.geometry, { x: (g.attributes && g.attributes.x != null) ? g.attributes.x : -16, y: (g.attributes && g.attributes.y != null) ? g.attributes.y : 16, width: (g.attributes && g.attributes.width != null) ? g.attributes.width : 32, height: (g.attributes && g.attributes.height != null) ? g.attributes.height : 32, }).then( (mesh) => { return { mesh: mesh, attributes: g.attributes, symbol: g.symbol }; }) ); break; case "multipoint": this.promises.push( this.tessellateMultipoint(g.geometry, { x: (g.attributes && g.attributes.x != null) ? g.attributes.x : -16, y: (g.attributes && g.attributes.y != null) ? g.attributes.y : 16, width: (g.attributes && g.attributes.width != null) ? g.attributes.width : 32, height: (g.attributes && g.attributes.height != null) ? g.attributes.height : 32, }).then( (mesh) => { return { mesh: mesh, attributes: g.attributes, symbol: g.symbol }; } ) ); break; case "polyline": this.promises.push( this.tessellatePolyline( g.geometry, (g.attributes && g.attributes.width != null) ? g.attributes.width : 20 ).then( (mesh) => { return { mesh: mesh, attributes: g.attributes, symbol: g.symbol }; } ) ); break; case "polygon": this.promises.push( this.tessellatePolygon(g.geometry).then( (mesh) => { return { mesh: mesh, attributes: g.attributes, symbol: g.symbol }; } ) ); break; } }, // Called internally from render(). updatePositions(renderParameters) { const gl = renderParameters.context; const stationary = renderParameters.stationary; const state = renderParameters.state; // If we are not stationary we simply update the `translationToCenter` vector. if (!stationary) { vec2.sub( this.translationToCenter, this.centerAtLastUpdate, state.center ); this.requestRender(); return; } // If we are stationary, the `layer.graphics` collection has not changed, and // we are centered on the `centerAtLastUpdate`, we do nothing. if ( !this.needsUpdate && this.translationToCenter[0] === 0 && this.translationToCenter[1] === 0 ) { return; } // Otherwise, we record the new encoded center, which imply a reset of the `translationToCenter` vector, // we record the update time, and we proceed to update the buffers. this.centerAtLastUpdate.set(state.center); this.translationToCenter[0] = 0; this.translationToCenter[1] = 0; this.needsUpdate = false; // Generate vertex data. const vertexCount = this.meshes.reduce((vertexCount, item) => { return vertexCount + item.mesh.vertices.length; }, 0); const indexCount = this.meshes.reduce((indexCount, item) => { return indexCount + item.mesh.indices.length; }, 0); const vertexData = new Float32Array(vertexCount * 8); const indexData = new Uint16Array(indexCount); let currentVertex = 0; let currentIndex = 0; for (let meshIndex = 0; meshIndex < this.meshes.length; ++meshIndex) { const item = this.meshes[meshIndex]; const mesh = item.mesh; const upright = (item.attributes && item.attributes.upright) ? 1 : 0; for (let i = 0; i < mesh.indices.length; ++i) { const idx = mesh.indices[i]; indexData[currentIndex] = currentVertex + idx; currentIndex++; } for (let i = 0; i < mesh.vertices.length; ++i) { const v = mesh.vertices[i]; vertexData[currentVertex * 8 + 0] = v.x - this.centerAtLastUpdate[0]; vertexData[currentVertex * 8 + 1] = v.y - this.centerAtLastUpdate[1]; vertexData[currentVertex * 8 + 2] = v.xOffset; vertexData[currentVertex * 8 + 3] = v.yOffset; vertexData[currentVertex * 8 + 4] = v.uTexcoord; vertexData[currentVertex * 8 + 5] = v.vTexcoord; vertexData[currentVertex * 8 + 6] = v.distance; vertexData[currentVertex * 8 + 7] = upright; currentVertex++; } } // Upload data to the GPU gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW); // Record number of indices. this.indexBufferSize = indexCount; } }); const CustomLayer = GraphicsLayer.createSubclass({ createLayerView: function (view) { if (view.type === "2d") { return new CustomLayerView2D({ view: view, layer: this }); } } }); export default CustomLayer;
09-02
HYPERVISOR_ERROR (20001) The hypervisor has encountered a fatal error. Arguments: Arg1: 0000000000000011 Arg2: 000007e34da00000 Arg3: 0000000000001005 Arg4: ffffe70000e05b10 Debugging Details: ------------------ KEY_VALUES_STRING: 1 Key : Analysis.CPU.mSec Value: 1156 Key : Analysis.Elapsed.mSec Value: 8841 Key : Analysis.IO.Other.Mb Value: 0 Key : Analysis.IO.Read.Mb Value: 1 Key : Analysis.IO.Write.Mb Value: 0 Key : Analysis.Init.CPU.mSec Value: 796 Key : Analysis.Init.Elapsed.mSec Value: 26769 Key : Analysis.Memory.CommitPeak.Mb Value: 109 Key : Analysis.Version.DbgEng Value: 10.0.27920.1001 Key : Analysis.Version.Description Value: 10.2506.23.01 amd64fre Key : Analysis.Version.Ext Value: 1.2506.23.1 Key : Bugcheck.Code.LegacyAPI Value: 0x20001 Key : Bugcheck.Code.TargetModel Value: 0x20001 Key : Dump.Attributes.AsUlong Value: 0x1808 Key : Dump.Attributes.DiagDataWrittenToHeader Value: 1 Key : Dump.Attributes.ErrorCode Value: 0x0 Key : Dump.Attributes.KernelGeneratedTriageDump Value: 1 Key : Dump.Attributes.LastLine Value: Dump completed successfully. Key : Dump.Attributes.ProgressPercentage Value: 0 Key : Failure.Bucket Value: 0x20001_11_7e34da00000_nt!HvlSkCrashdumpCallbackRoutine Key : Failure.Hash Value: {1255aeda-ea71-8be3-7c8e-e5223f3c8b2d} Key : Hypervisor.Enlightenments.ValueHex Value: 0x7497cf94 Key : Hypervisor.Flags.AnyHypervisorPresent Value: 1 Key : Hypervisor.Flags.ApicEnlightened Value: 1 Key : Hypervisor.Flags.ApicVirtualizationAvailable Value: 0 Key : Hypervisor.Flags.AsyncMemoryHint Value: 0 Key : Hypervisor.Flags.CoreSchedulerRequested Value: 0 Key : Hypervisor.Flags.CpuManager Value: 1 Key : Hypervisor.Flags.DeprecateAutoEoi Value: 0 Key : Hypervisor.Flags.DynamicCpuDisabled Value: 1 Key : Hypervisor.Flags.Epf Value: 0 Key : Hypervisor.Flags.ExtendedProcessorMasks Value: 1 Key : Hypervisor.Flags.HardwareMbecAvailable Value: 1 Key : Hypervisor.Flags.MaxBankNumber Value: 0 Key : Hypervisor.Flags.MemoryZeroingControl Value: 0 Key : Hypervisor.Flags.NoExtendedRangeFlush Value: 0 Key : Hypervisor.Flags.NoNonArchCoreSharing Value: 1 Key : Hypervisor.Flags.Phase0InitDone Value: 1 Key : Hypervisor.Flags.PowerSchedulerQos Value: 0 Key : Hypervisor.Flags.RootScheduler Value: 0 Key : Hypervisor.Flags.SynicAvailable Value: 1 Key : Hypervisor.Flags.UseQpcBias Value: 0 Key : Hypervisor.Flags.Value Value: 38408431 Key : Hypervisor.Flags.ValueHex Value: 0x24a10ef Key : Hypervisor.Flags.VpAssistPage Value: 1 Key : Hypervisor.Flags.VsmAvailable Value: 1 Key : Hypervisor.RootFlags.AccessStats Value: 1 Key : Hypervisor.RootFlags.CrashdumpEnlightened Value: 1 Key : Hypervisor.RootFlags.CreateVirtualProcessor Value: 1 Key : Hypervisor.RootFlags.DisableHyperthreading Value: 0 Key : Hypervisor.RootFlags.HostTimelineSync Value: 1 Key : Hypervisor.RootFlags.HypervisorDebuggingEnabled Value: 0 Key : Hypervisor.RootFlags.IsHyperV Value: 1 Key : Hypervisor.RootFlags.LivedumpEnlightened Value: 1 Key : Hypervisor.RootFlags.MapDeviceInterrupt Value: 1 Key : Hypervisor.RootFlags.MceEnlightened Value: 1 Key : Hypervisor.RootFlags.Nested Value: 0 Key : Hypervisor.RootFlags.StartLogicalProcessor Value: 1 Key : Hypervisor.RootFlags.Value Value: 1015 Key : Hypervisor.RootFlags.ValueHex Value: 0x3f7 Key : Stack.Pointer Value: NMI Key : WER.System.BIOSRevision Value: 5.35.0.0 BUGCHECK_CODE: 20001 BUGCHECK_P1: 11 BUGCHECK_P2: 7e34da00000 BUGCHECK_P3: 1005 BUGCHECK_P4: ffffe70000e05b10 FILE_IN_CAB: 101325-16875-01.dmp DUMP_FILE_ATTRIBUTES: 0x1808 Kernel Generated Triage Dump FAULTING_THREAD: ffff9506a83c7080 BLACKBOXBSD: 1 (!blackboxbsd) BLACKBOXNTFS: 1 (!blackboxntfs) BLACKBOXPNP: 1 (!blackboxpnp) BLACKBOXWINLOGON: 1 (!blackboxwinlogon) CUSTOMER_CRASH_COUNT: 1 PROCESS_NAME: bf6.exe STACK_TEXT: ffffe580`e5adfca8 fffff800`e4f86fea : 00000000`00020001 00000000`00000011 000007e3`4da00000 00000000`00001005 : nt!KeBugCheckEx ffffe580`e5adfcb0 fffff800`e4fb3861 : ffff9506`8869ffb0 fffff800`e4fc5ed6 ffffe580`e5af0990 ffffe580`e5adfd30 : nt!HvlSkCrashdumpCallbackRoutine+0x8a ffffe580`e5adfcf0 fffff800`e50ab9c2 : 00000000`00000100 ffffe580`e5adfef0 00000000`00000000 00000000`00000000 : nt!KiProcessNMI+0xb1 ffffe580`e5adfd30 fffff800`e50ab72e : 00000000`00000000 00000000`00000100 ffffe580`e5adfef0 00000000`00000000 : nt!KxNmiInterrupt+0x82 ffffe580`e5adfe70 00000001`43956f62 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiNmiInterrupt+0x26e 00000000`7e13fac0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00000001`43956f62 SYMBOL_NAME: nt!HvlSkCrashdumpCallbackRoutine+8a MODULE_NAME: nt IMAGE_NAME: ntkrnlmp.exe IMAGE_VERSION: 10.0.26100.6584 STACK_COMMAND: .process /r /p 0xffff9506aaaf0080; .thread 0xffff9506a83c7080 ; kb BUCKET_ID_FUNC_OFFSET: 8a FAILURE_BUCKET_ID: 0x20001_11_7e34da00000_nt!HvlSkCrashdumpCallbackRoutine OSPLATFORM_TYPE: x64 OSNAME: Windows 10 FAILURE_ID_HASH: {1255aeda-ea71-8be3-7c8e-e5223f3c8b2d} Followup: MachineOwner --------- 这是怎么回事
10-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值