我遇到了"CorruptedString"(解决方案).以下是本书中的以下程序代码:
var s = "Hello";
string.Intern(s);
unsafe
{
fixed (char* c = s)
for (int i = 0; i < s.Length; i++)
c[i] = 'a';
}
Console.WriteLine("Hello"); // Displays: "aaaaa"
Run Code Online (Sandbox Code Playgroud)
为什么这个节目会显示"aaaaa"?我理解这个程序如下:
string.Intern(s)
实际上什么也没做,因为CLR保留了"Hello"字符串 - 它只返回保留的"Hello"字符串的地址(对象s具有相同的地址)据我了解实习池,它就像某种字符串字符串.或许我错过了什么?
我有这样简单的程序:
public class Foo
{
public Foo()
{
}
public int MyInt { get; set; } = 10;
public List<int> MyList { get; set; } = new List<int>();
}
public class Program
{
static public void Main()
{
Console.WriteLine(new Foo().MyInt);
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
我决定看看这样的程序的CIL代码(我对Foo的构造函数感兴趣).就这个:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 26 (0x1a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.s 10
IL_0003: stfld int32 Foo::'<MyInt>k__BackingField'
IL_0008: ldarg.0
IL_0009: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_000e: …
Run Code Online (Sandbox Code Playgroud) 使用返回void的函数的三元运算符是否安全?像这样的东西:
void foo1(){}
void foo2(){}
//////////////
bool to_use_1 = ....;
to_use_1 ? foo1() : foo2();
Run Code Online (Sandbox Code Playgroud)
编译器可以删除此代码吗?假设它会将这些函数视为纯函数,并执行删除这些调用的激励优化
我想动态生成程序集,它可以具有不同结构的函数.更准确地说,这些函数可以是递归的,它们可以调用同一程序System.Reflection
集中的其他函数等.我找到了理论上提供工具的模块,但实际上我遇到了这种方法的许多缺点.例如 - 我不能通过TypeBuilder
和MethodBuilder
类生成递归函数,因为将抛出异常(使用不完整类型).我了解到我可以通过以下方式生成自递归函数IlGenerator
- 但它太麻烦了 - 我希望有一种更简单的方法可以做到这一点.
这是我的程序,它演示了这个问题(在生成方法时Fact
抛出以下异常:
Run Code Online (Sandbox Code Playgroud)Exception thrown: 'System.NotSupportedException' in mscorlib.dll Additional information: Specified method is not supported..
代码:
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Linq.Expressions;
namespace GenericFuncs
{
public class ProgramBuilder
{
public Type createMyProgram()
{
var assmName = new AssemblyName("DynamicAssemblyExample");
var assmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assmName, AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = assmBuilder.DefineDynamicModule(assmName.Name, assmName.Name + ".dll");
var myProgramType = buildMyProgram(moduleBuilder, moduleBuilder.DefineType("MyProgram", TypeAttributes.Public));
assmBuilder.Save(assmName.Name + ".dll");
return myProgramType;
}
private …
Run Code Online (Sandbox Code Playgroud) 假设我有以下程序:
static void SomeMethod(Func<int, int> otherMethod)
{
otherMethod(1);
}
static int OtherMethod(int x)
{
return x;
}
static void Main(string[] args)
{
SomeMethod(OtherMethod);
SomeMethod(x => OtherMethod(x));
SomeMethod(x => OtherMethod(x));
}
Run Code Online (Sandbox Code Playgroud)
我无法理解编译的il代码(它使用了额外的代码).这是简化版:
class C
{
public static C c;
public static Func<int, int> foo;
public static Func<int, int> foo1;
static C()
{
c = new C();
}
C(){}
public int b(int x)
{
return OtherMethod(x);
}
public int b1(int x)
{
return OtherMethod(x);
}
}
static void Main()
{
SomeMethod(new Func<int, …
Run Code Online (Sandbox Code Playgroud) 据我了解,泛型是一种优雅的解决方案,可以解决在通用集合中出现的额外装箱/拆箱过程的问题List
.但我无法理解泛型如何解决在泛型函数中使用接口的问题.换句话说,如果我想传递一个实现泛型方法接口的值实例,那么会执行装箱吗?编译器如何处理这种情况?
据我所知,为了使用接口方法,值实例应该被加框,因为调用"虚拟"函数需要包含在引用对象中的"私有"信息(它包含在所有引用对象中(它还具有同步)块))
这就是为什么我决定分析IL
一个简单程序的代码,看看是否在泛型函数中使用了任何装箱操作:
public class main_class
{
public interface INum<a> { a add(a other); }
public struct MyInt : INum<MyInt>
{
public MyInt(int _my_int) { Num = _my_int; }
public MyInt add(MyInt other) => new MyInt(Num + other.Num);
public int Num { get; }
}
public static a add<a>(a lhs, a rhs) where a : INum<a> => lhs.add(rhs);
public static void Main()
{
Console.WriteLine(add(new MyInt(1), new MyInt(2)).Num);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这add(new MyInt(1), new MyInt(2))
将使用装箱操作,因为添加泛型方法使用INum<a> …
我想myscheme://foo
通过我的应用程序像在任何浏览器中一样处理查询myscheme.exe
。
据我了解,解决方案将取决于所使用操作系统的版本。对于旧操作系统(直到 Windows 7),只需将记录保存在注册表中:
HKEY_CLASSES_ROOT
myscheme
(Default) = "URL:Myscheme Protocol"
URL Protocol = ""
DefaultIcon
(Default) = "myscheme.exe,1"
shell
open
command
(Default) = "C:\Program Files\Myscheme\myscheme.exe" "%1"
Run Code Online (Sandbox Code Playgroud)
不幸的是,将应用程序注册到 URI 方案声明这种方式已被弃用。我不应该再使用这个 API。页面上的推荐版本microsoft-edge
(它不包含有关它的信息)!!!
于是,我开始研究它windows 8
。我遇到了文件类型和 URI 关联模型,它说在Windows 8
应用程序中不再能够以编程方式将自己设置为文件类型或 URI 的默认处理程序。据我所知,新架构使用通知系统,用户通过特殊提示控制默认应用程序。但是默认程序说它对 Windows 10 不再有效(探索参考已经死了!)。
那么,如何在 Windows 10 中正确处理自定义协议呢?不幸的是,Windows 的文档很糟糕。那么不同版本的操作系统呢?我应该对不同的版本使用不同的技术吗?
PS请不要将此问题标记为重复。其他问题,例如如何在 Windows 中注册自定义 URL 协议?,如何创建自己的 URL 协议?(例如:so://...)提出已弃用的解决方案。
对不起,我的英语不好。
我探索了c#源代码参考.我偶然发现有趣的IArithmetic<T>
界面.例如,Int32
,Double
包含评论的实现IArithmetic
接口.我对这些细节很感兴趣.据我所知,它试图添加"支持"算术运算.但为什么他们评论?是否添加支持通用"运营商"的方法不好?
我知道 Greiner-Hormann 和 Vatti 的两种常见算法。他们使用多边形。我想在贝塞尔曲线路径上实现布尔运算。我想扩展这些算法以处理贝塞尔曲线路径。但这是数值问题。贝塞尔曲线路径剪切的最佳方法是什么?(以及对任意多边形(具有自交集)的 Greiner-Hormann 算法的最佳修改是什么)
这是我的解决方案的结构:
A.lib
定义:
int a(void) { return 1; }
Run Code Online (Sandbox Code Playgroud)
B.lib
定义:
int b(void) { return a(); }
Run Code Online (Sandbox Code Playgroud)
C.lib
定义:
int c(void) { return a() * 2; }
Run Code Online (Sandbox Code Playgroud)
SharedStaticLibsTest.exe
定义:
int main(void) { std::cout << b() + c() << std::endl; return 0;}
Run Code Online (Sandbox Code Playgroud)
我决定检查(通过DumpBin
)嵌入到结果应用程序中的代码。事实证明,B
和C
库使用的唯一实例A
库。有没有办法(出于教育目的)使用A
insideB
和 的两个不同实例C
?也许这些东西有特定的链接器选项?我明白,这种行为可能会产生意想不到的副作用,这取决于A
库的逻辑。
PS 我通过在项目的属性中直接包含 .lib 文件来替换对项目的引用。现在B
,C
项目有一个项目的副本A
。但是最终项目仍然只有A
库的副本。我不知道链接器如何解决这个问题。
c# ×6
c++ ×2
algorithm ×1
cil ×1
clr ×1
constructor ×1
generics ×1
jit ×1
linker ×1
math ×1
protocols ×1
reflection ×1
string ×1
url-scheme ×1
visual-c++ ×1
winapi ×1
windows ×1