相关疑难解决方法(0)

为什么TypedReference在幕后?它如此快速和安全......几乎是神奇的!

警告:这个问题有点异端......宗教程序员总是遵守良好做法,请不要阅读.:)

有谁知道为什么不鼓励使用TypedReference(隐含地,缺乏文档)?

我已经找到了很好的用途,例如通过不应该是通用的函数传递泛型参数(当使用object可能是过度杀手或缓慢,如果你需要值类型时),当你需要一个不透明的指针时,或者当你需要快速访问数组元素时,你在运行时找到它的规范(使用Array.InternalGetReference).由于CLR甚至不允许错误使用此类型,为什么不鼓励?它似乎不安全或任何东西......


我找到的其他用途TypedReference:

C#中的"Specializing"泛型(这是类型安全的):

static void foo<T>(ref T value)
{
    //This is the ONLY way to treat value as int, without boxing/unboxing objects
    if (value is int)
    { __refvalue(__makeref(value), int) = 1; }
    else { value = default(T); }
}
Run Code Online (Sandbox Code Playgroud)

编写适用于通用指针的代码(如果误用,这是非常不安全的,但如果使用正确则快速且安全):

//This bypasses the restriction that you can't have a pointer to T,
//letting you write very high-performance generic code.
//It's dangerous if you don't know what you're doing, …
Run Code Online (Sandbox Code Playgroud)

c# typedreference

127
推荐指数
2
解决办法
1万
查看次数

如何使用IL改变盒装结构

想象一下,我们有一个可变的struct(是的,不要开始):

public struct MutableStruct
{
    public int Foo { get; set; }
    public override string ToString()
    {
        return Foo.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用反射,我们可以获取一个盒装实例,struct并在框内变异:

// this is basically what we want to emulate
object obj = new MutableStruct { Foo = 123 };
obj.GetType().GetProperty("Foo").SetValue(obj, 456);
System.Console.WriteLine(obj); // "456"
Run Code Online (Sandbox Code Playgroud)

我会喜欢做的是写一些IL可以做同样的,因为这-但速度更快.我是一个元编程迷; p

拆箱 - 任何值并使用常规IL改变值是微不足道的 - 但是你不能只是在之后调用它,因为这将创建一个不同的框.我我们需要做的是将它复制到现有的盒子上.我已经调查了ldobj/ stobj,但那些似乎没有做到这一点(除非我遗漏了什么).

那么:是否存在这样做的机制?或者我必须限制自己反思以执行盒装structs 的就地更新?

换句话说:什么... evil goes here...

var method = …
Run Code Online (Sandbox Code Playgroud)

.net c# metaprogramming ilgenerator

26
推荐指数
2
解决办法
1119
查看次数

生成动态方法以设置结构的字段而不是使用反射

假设我有以下代码更新struct使用反射的字段.由于struct实例被复制到DynamicUpdate方法中,因此需要在传递之前将其装箱到对象.

struct Person
{
    public int id;
}

class Test
{
    static void Main()
    {
        object person = RuntimeHelpers.GetObjectValue(new Person());
        DynamicUpdate(person);
        Console.WriteLine(((Person)person).id); // print 10
    }

    private static void DynamicUpdate(object o)
    {
        FieldInfo field = typeof(Person).GetField("id");
        field.SetValue(o, 10);
    }
}
Run Code Online (Sandbox Code Playgroud)

代码工作正常.现在,假设我不想使用反射,因为它很慢.相反,我想生成一些CIL直接修改id字段并将该CIL转换为可重用的委托(例如,使用动态方法功能).特别是,我想用s/t替换上面的代码,如下所示:

static void Main()
{
    var action = CreateSetIdDelegate(typeof(Person));
    object person = RuntimeHelpers.GetObjectValue(new Person());
    action(person, 10);
    Console.WriteLine(((Person)person).id); // print 10
}

private static Action<object, object> CreateSetIdDelegate(Type t)
{
    // build dynamic method …
Run Code Online (Sandbox Code Playgroud)

.net c# reflection reflection.emit dynamic-method

11
推荐指数
3
解决办法
7705
查看次数