未验证 提交 df45afd8 编写于 作者: T Thays Grazia 提交者: GitHub

[wasm][debugger] Fix chinese character in project name (#74516)

* Fix chinese character in project name

* Adding more tests as suggested by @radical
Renaming variable as suggested by @radical

* Update src/mono/wasm/debugger/tests/debugger-test-chinese-char-in-path-ㄨ/debugger-test-chinese-char-in-path-ㄨ.csproj
Co-authored-by: NAnkit Jain <radical@gmail.com>
上级 1c675281
......@@ -1467,11 +1467,12 @@ public async IAsyncEnumerable<SourceFile> Load(SessionId id, string[] loaded_fil
continue;
try
{
string unescapedFileName = Uri.UnescapeDataString(file_name);
steps.Add(
new DebugItem
{
Url = file_name,
Data = context.SdbAgent.GetBytesFromAssemblyAndPdb(Path.GetFileName(file_name), token)
Data = context.SdbAgent.GetBytesFromAssemblyAndPdb(Path.GetFileName(unescapedFileName), token)
});
}
catch (Exception e)
......
......@@ -51,35 +51,37 @@ public async Task DebugHotReloadMethodUnchanged()
CheckNumber(locals, "a", 10);
}
[ConditionalFact(nameof(RunningOnChrome))]
public async Task DebugHotReloadMethodAddBreakpoint()
[ConditionalTheory(nameof(RunningOnChrome))]
[InlineData("ApplyUpdateReferencedAssembly")]
[InlineData("ApplyUpdateReferencedAssemblyChineseCharInPathㄨ")]
public async Task DebugHotReloadMethodAddBreakpoint(string assembly_name)
{
int line = 30;
await SetBreakpoint(".*/MethodBody1.cs$", line, 12, use_regex: true);
var pause_location = await LoadAssemblyAndTestHotReload(
Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.dll"),
Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.pdb"),
Path.Combine(DebuggerTestAppPath, "../wasm/ApplyUpdateReferencedAssembly.dll"),
Path.Combine(DebuggerTestAppPath, $"{assembly_name}.dll"),
Path.Combine(DebuggerTestAppPath, $"{assembly_name}.pdb"),
Path.Combine(DebuggerTestAppPath, $"../wasm/{assembly_name}.dll"),
"MethodBody3", "StaticMethod3", expectBpResolvedEvent: true);
var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
CheckNumber(locals, "a", 10);
pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 30, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3");
pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", $"dotnet://{assembly_name}.dll/MethodBody1.cs", 30, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3");
locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
CheckNumber(locals, "b", 15);
pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 30, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3");
pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", $"dotnet://{assembly_name}.dll/MethodBody1.cs", 30, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3");
locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
await CheckBool(locals, "c", true);
await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 31, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
await StepAndCheck(StepKind.Over, $"dotnet://{assembly_name}.dll/MethodBody1.cs", 31, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
locals_fn: async (locals) =>
{
CheckNumber(locals, "d", 10);
await Task.CompletedTask;
}
);
await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 32, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
await StepAndCheck(StepKind.Over, $"dotnet://{assembly_name}.dll/MethodBody1.cs", 32, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
locals_fn: async (locals) =>
{
CheckNumber(locals, "d", 10);
......@@ -87,7 +89,7 @@ public async Task DebugHotReloadMethodAddBreakpoint()
await Task.CompletedTask;
}
);
await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 33, 8, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
await StepAndCheck(StepKind.Over, $"dotnet://{assembly_name}.dll/MethodBody1.cs", 33, 8, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
locals_fn: async (locals) =>
{
CheckNumber(locals, "d", 10);
......@@ -217,12 +219,14 @@ public async Task DebugHotReloadMethodUnchangedUsingSDB()
CheckLocation("dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 21, 12, scripts, top_frame["location"]);
}
[ConditionalFact(nameof(RunningOnChrome))]
public async Task DebugHotReloadMethodAddBreakpointUsingSDB()
[ConditionalTheory(nameof(RunningOnChrome))]
[InlineData("ApplyUpdateReferencedAssembly")]
[InlineData("ApplyUpdateReferencedAssemblyChineseCharInPathㄨ")]
public async Task DebugHotReloadMethodAddBreakpointUsingSDB(string assembly_name)
{
string asm_file = Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.dll");
string pdb_file = Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.pdb");
string asm_file_hot_reload = Path.Combine(DebuggerTestAppPath, "../wasm/ApplyUpdateReferencedAssembly.dll");
string asm_file = Path.Combine(DebuggerTestAppPath, $"{assembly_name}.dll");
string pdb_file = Path.Combine(DebuggerTestAppPath, $"{assembly_name}.pdb");
string asm_file_hot_reload = Path.Combine(DebuggerTestAppPath, $"../wasm/{assembly_name}.dll");
int line = 30;
await SetBreakpoint(".*/MethodBody1.cs$", line, 12, use_regex: true);
......@@ -238,7 +242,7 @@ public async Task DebugHotReloadMethodAddBreakpointUsingSDB()
JToken top_frame = pause_location["callFrames"]?[0];
AssertEqual("ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3", top_frame?["functionName"]?.Value<string>(), top_frame?.ToString());
CheckLocation("dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 30, 12, scripts, top_frame["location"]);
CheckLocation($"dotnet://{assembly_name}.dll/MethodBody1.cs", 30, 12, scripts, top_frame["location"]);
locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
CheckNumber(locals, "b", 15);
......@@ -249,19 +253,19 @@ public async Task DebugHotReloadMethodAddBreakpointUsingSDB()
top_frame = pause_location["callFrames"]?[0];
AssertEqual("ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3", top_frame?["functionName"]?.Value<string>(), top_frame?.ToString());
CheckLocation("dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 30, 12, scripts, top_frame["location"]);
CheckLocation($"dotnet://{assembly_name}.dll/MethodBody1.cs", 30, 12, scripts, top_frame["location"]);
locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
await CheckBool(locals, "c", true);
await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 31, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
await StepAndCheck(StepKind.Over, $"dotnet://{assembly_name}.dll/MethodBody1.cs", 31, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
locals_fn: async (locals) =>
{
CheckNumber(locals, "d", 10);
await Task.CompletedTask;
}
);
await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 32, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
await StepAndCheck(StepKind.Over, $"dotnet://{assembly_name}.dll/MethodBody1.cs", 32, 12, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
locals_fn: async (locals) =>
{
CheckNumber(locals, "d", 10);
......@@ -269,7 +273,7 @@ public async Task DebugHotReloadMethodAddBreakpointUsingSDB()
await Task.CompletedTask;
}
);
await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 33, 8, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
await StepAndCheck(StepKind.Over, $"dotnet://{assembly_name}.dll/MethodBody1.cs", 33, 8, "ApplyUpdateReferencedAssembly.MethodBody3.StaticMethod3",
locals_fn: async (locals) =>
{
CheckNumber(locals, "d", 10);
......
......@@ -735,23 +735,25 @@ JObject FindFrame(JObject pause_location, string function_name)
?.Where(f => f["functionName"]?.Value<string>() == function_name)
?.FirstOrDefault();
[ConditionalFact(nameof(RunningOnChrome))]
public async Task DebugLazyLoadedAssemblyWithPdb()
[ConditionalTheory(nameof(RunningOnChrome))]
[InlineData("lazy-debugger-test")]
[InlineData("lazy-debugger-test-chinese-char-in-path-ㄨ")]
public async Task DebugLazyLoadedAssemblyWithPdb(string assembly_name)
{
Task<JObject> bpResolved = WaitForBreakpointResolvedEvent();
int line = 9;
await SetBreakpoint(".*/lazy-debugger-test.cs$", line, 0, use_regex: true);
await LoadAssemblyDynamically(
Path.Combine(DebuggerTestAppPath, "lazy-debugger-test.dll"),
Path.Combine(DebuggerTestAppPath, "lazy-debugger-test.pdb"));
Path.Combine(DebuggerTestAppPath, $"{assembly_name}.dll"),
Path.Combine(DebuggerTestAppPath, $"{assembly_name}.pdb"));
var source_location = "dotnet://lazy-debugger-test.dll/lazy-debugger-test.cs";
var source_location = $"dotnet://{assembly_name}.dll/lazy-debugger-test.cs";
Assert.Contains(source_location, scripts.Values);
await bpResolved;
var pause_location = await EvaluateAndCheck(
"window.setTimeout(function () { invoke_static_method('[lazy-debugger-test] LazyMath:IntAdd', 5, 10); }, 1);",
"window.setTimeout(function () { invoke_static_method('[" + assembly_name + "] LazyMath:IntAdd', 5, 10); }, 1);",
source_location, line, 8,
"LazyMath.IntAdd");
var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
......@@ -1086,5 +1088,17 @@ public async Task InspectThisThatInheritsFromClassNonUserCode(string class_name,
}
);
}
[ConditionalFact(nameof(RunningOnChrome))]
public async Task SetBreakpointInProjectWithChineseCharactereInPath()
{
var bp = await SetBreakpointInMethod("debugger-test-chinese-char-in-path-ㄨ.dll", "DebuggerTests.CheckChineseCharacterInPath", "Evaluate", 1);
await EvaluateAndCheck(
$"window.setTimeout(function() {{ invoke_static_method ('[debugger-test-chinese-char-in-path-] DebuggerTests.CheckChineseCharacterInPath:Evaluate'); }}, 1);",
"dotnet://debugger-test-chinese-char-in-path-ㄨ.dll/test.cs",
bp.Value["locations"][0]["lineNumber"].Value<int>(),
bp.Value["locations"][0]["columnNumber"].Value<int>(),
$"DebuggerTests.CheckChineseCharacterInPath.Evaluate");
}
}
}
<Project Sdk="Microsoft.NET.Sdk" TreatAsLocalProperty="EnableAggressiveTrimming;PublishTrimmed">
<PropertyGroup>
<TestRuntime>true</TestRuntime>
<DeltaScript>deltascript.json</DeltaScript>
<OutputType>library</OutputType>
<IsTestProject>false</IsTestProject>
<IsTestSupportProject>true</IsTestSupportProject>
<!-- to call AsssemblyExtensions.ApplyUpdate we need Optimize=false, EmitDebugInformation=true in all configurations -->
<Optimize>false</Optimize>
<EmitDebugInformation>true</EmitDebugInformation>
<!-- hot reload is not compatible with trimming -->
<EnableAggressiveTrimming>false</EnableAggressiveTrimming>
<PublishTrimmed>false</PublishTrimmed>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EmbedAllSources>true</EmbedAllSources>
<!-- FIXME: issue -->
<DisableSourceLink>true</DisableSourceLink>
</PropertyGroup>
<ItemGroup>
<Compile Include="MethodBody0.cs" />
<Compile Include="MethodBody1.cs" />
</ItemGroup>
<ItemGroup>
<!-- This package from https://github.com/dotnet/hotreload-utils provides
targets that read the json delta script and generates deltas based on the baseline assembly and the modified sources.
Projects must define the DeltaScript property that specifies the (relative) path to the json script.
Deltas will be emitted next to the output assembly. Deltas will be copied when the current
project is referenced from other other projects.
-->
<PackageReference Include="Microsoft.DotNet.HotReload.Utils.Generator.BuildTool" Version="$(MicrosoftDotNetHotReloadUtilsGeneratorBuildToolVersion)" />
</ItemGroup>
</Project>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System;
namespace ApplyUpdateReferencedAssembly
{
public class MethodBodyUnchangedAssembly {
public static string StaticMethod1 () {
Console.WriteLine("original");
return "ok";
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System;
//keep the same line number for class in the original file and the updates ones
namespace ApplyUpdateReferencedAssembly
{
public class MethodBody1 {
public static string StaticMethod1 () {
Console.WriteLine("original");
int a = 10;
Debugger.Break();
return "OLD STRING";
}
}
public class MethodBody2 {
public static string StaticMethod1 () {
Console.WriteLine("original");
int a = 10;
Debugger.Break();
return "OLD STRING";
}
}
public class MethodBody3 {
public static string StaticMethod3 () {
int a = 10;
Console.WriteLine("original");
return "OLD STRING";
}
}
public class MethodBody4 {
public static void StaticMethod4 () {
}
}
public class MethodBody5 {
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a line that will not be changed");
Console.WriteLine("original");
}
}
public class MethodBody6 {
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a line that will not be changed");
Console.WriteLine("original");
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System;
//keep the same line number for class in the original file and the updates ones
namespace ApplyUpdateReferencedAssembly
{
public class MethodBody1 {
public static string StaticMethod1 () {
Console.WriteLine("v1");
double b = 15;
Debugger.Break();
return "NEW STRING";
}
}
public class MethodBody2 {
public static string StaticMethod1 () {
Console.WriteLine("original");
int a = 10;
Debugger.Break();
return "OLD STRING";
}
}
public class MethodBody3 {
public static string StaticMethod3 () {
float b = 15;
Console.WriteLine("v1");
return "NEW STRING";
}
}
public class MethodBody4 {
public static void StaticMethod4 () {
int a = 10;
int b = 20;
Console.WriteLine(a + b);
Console.WriteLine(a + b);
Console.WriteLine(a + b);
}
}
public class MethodBody5 {
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a line that will not be changed");
Console.WriteLine("beforeoriginal");
Console.WriteLine("original");
}
}
public class MethodBody6 {
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a line that will not be changed");
Console.WriteLine("original");
}
public static void NewMethodStatic () {
int i = 20;
newStaticField = 10;
Console.WriteLine($"add a breakpoint in the new static method, look at locals {newStaticField}");
/*var newvar = new MethodBody6();
newvar.NewMethodInstance (10);*/
}
public static int newStaticField;
}
public class MethodBody7 {
public static int staticField;
int attr1;
string attr2;
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a method in a new class");
Console.WriteLine("original");
MethodBody7 newvar = new MethodBody7();
staticField = 80;
newvar.InstanceMethod();
}
public void InstanceMethod () {
int aLocal = 50;
attr1 = 15;
attr2 = "20";
Console.WriteLine($"add a breakpoint the instance method of the new class");
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System;
//keep the same line number for class in the original file and the updates ones
namespace ApplyUpdateReferencedAssembly
{
public class MethodBody1 {
public static string StaticMethod1 ()
{
Console.WriteLine("v2");
bool c = true;
Debugger.Break();
return "NEWEST STRING";
}
}
public class MethodBody2 {
public static string StaticMethod1 () {
Console.WriteLine("original");
int a = 10;
Debugger.Break();
return "OLD STRING";
}
}
public class MethodBody3 {
public static string StaticMethod3 () {
bool c = true;
int d = 10;
int e = 20;
int f = 50;
return "NEWEST STRING";
}
}
public class MethodBody4 {
public static void StaticMethod4 () {
}
}
public class MethodBody5 {
public static void StaticMethod1 () {
Console.WriteLine("beforeoriginal");
Console.WriteLine("original");
}
}
public class MethodBody6 {
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a line that will not be changed");
Console.WriteLine("original");
}
public static void NewMethodStatic () {
int i = 20;
newStaticField = 10;
Console.WriteLine($"add a breakpoint in the new static method, look at locals {newStaticField}");
/*var newvar = new MethodBody6();
newvar.NewMethodInstance (10);*/
}
public static int newStaticField;
}
public class MethodBody7 {
public static int staticField;
int attr1;
string attr2;
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a method in a new class");
Console.WriteLine("original");
MethodBody7 newvar = new MethodBody7();
staticField = 80;
newvar.InstanceMethod();
}
public void InstanceMethod () {
int aLocal = 50;
attr1 = 15;
attr2 = "20";
Console.WriteLine($"add a breakpoint the instance method of the new class");
}
}
public class MethodBody8 {
public static int staticField;
int attr1;
string attr2;
public static void StaticMethod1 () {
Console.WriteLine("breakpoint in a method in a new class");
Console.WriteLine("original");
MethodBody8 newvar = new MethodBody8();
staticField = 80;
newvar.InstanceMethod();
}
public void InstanceMethod () {
int aLocal = 50;
attr1 = 15;
attr2 = "20";
Console.WriteLine($"add a breakpoint the instance method of the new class");
}
}
}
{
"changes": [
{"document": "MethodBody1.cs", "update": "MethodBody1_v1.cs"},
{"document": "MethodBody1.cs", "update": "MethodBody1_v2.cs"},
]
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- pdb2pdb.exe does not seem to support special characters in the path, and exits with -1 -->
<PublishWindowsPdb>false</PublishWindowsPdb>
</PropertyGroup>
</Project>
namespace DebuggerTests
{
public class CheckChineseCharacterInPath
{
public static void Evaluate()
{
var a = 123;
}
}
}
......@@ -20,7 +20,9 @@
<!-- We want to bundle these assemblies, so build them first -->
<ProjectReference Include="..\ApplyUpdateReferencedAssembly\ApplyUpdateReferencedAssembly.csproj" />
<ProjectReference Include="..\ApplyUpdateReferencedAssemblyChineseCharInPathㄨ\ApplyUpdateReferencedAssemblyChineseCharInPathㄨ.csproj" />
<ProjectReference Include="..\debugger-test-special-char-in-path-#@\debugger-test-special-char-in-path.csproj" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\debugger-test-chinese-char-in-path-ㄨ\debugger-test-chinese-char-in-path-ㄨ.csproj" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\debugger-test-with-source-link\debugger-test-with-source-link.csproj" ReferenceOutputAssembly="false" Private="true" />
<ProjectReference Include="..\debugger-test-without-debug-symbols-to-load\debugger-test-without-debug-symbols-to-load.csproj" Private="true" />
<ProjectReference Include="..\debugger-test-with-non-user-code-class\debugger-test-with-non-user-code-class.csproj" Private="true" />
......@@ -29,6 +31,7 @@
<!-- These are only loaded dynamically -->
<_AssemblyForDynamicLoading Include="lazy-debugger-test" />
<_AssemblyForDynamicLoading Include="lazy-debugger-test-chinese-char-in-path-ㄨ" />
<_AssemblyForDynamicLoading Include="debugger-test-with-full-debug-type" />
<_AssemblyForDynamicLoading Include="debugger-test-with-pdb-deleted" />
<_AssemblyForDynamicLoading Include="debugger-test-without-debug-symbols" />
......@@ -53,6 +56,7 @@
<ItemGroup>
<WasmAssembliesToBundle Include="$(OutDir)\$(TargetFileName)" />
<WasmAssembliesToBundle Include="$(OutDir)\debugger-test-special-char-in-path.dll" />
<WasmAssembliesToBundle Include="$(OutDir)\debugger-test-chinese-char-in-path-ㄨ.dll" />
<WasmAssembliesToBundle Include="$(OutDir)\debugger-test-with-source-link.dll" />
<WasmAssembliesToBundle Include="$(OutDir)\debugger-test-without-debug-symbols-to-load.dll" />
<WasmAssembliesToBundle Include="$(OutDir)\debugger-test-with-non-user-code-class.dll" />
......@@ -78,6 +82,9 @@
<TrimmerRootAssembly
Condition="$([System.String]::Copy('%(ResolvedFileToPublish.FileName)%(ResolvedFileToPublish.Extension)').EndsWith('ApplyUpdateReferencedAssembly.dll'))"
Include="%(ResolvedFileToPublish.FullPath)" />
<TrimmerRootAssembly
Condition="$([System.String]::Copy('%(ResolvedFileToPublish.FileName)%(ResolvedFileToPublish.Extension)').EndsWith('ApplyUpdateReferencedAssemblyChineseCharInPathㄨ.dll'))"
Include="%(ResolvedFileToPublish.FullPath)" />
</ItemGroup>
</Target>
<Target Name="IncludeDeltasInWasmBundle"
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
public partial class LazyMath
{
public static int IntAdd(int a, int b)
{
int c = a + b;
return c;
}
}
namespace DebuggerTests
{
public class ClassToCheckFieldValue
{
public int valueToCheck;
public ClassToCheckFieldValue()
{
valueToCheck = 20;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册