是否有一种众所周知的方法来模拟c#中的可变参数模板功能?
例如,我想编写一个带有任意参数集的lambda的方法.这是我想要的伪代码:
void MyMethod<T1,T2,...,TReturn>(Fun<T1,T2, ..., TReturn> f)
{
}
Run Code Online (Sandbox Code Playgroud)
谢谢
TypedReference在实际代码中实际使用的结构是否有任何实际用途?
编辑:.Net框架在重载中使用它们,Console.WriteLine并String.Concat从__arglist参数构建数组并将其传递给正常的params重载.为什么存在这些过载?
我想修改一个结构的字段,该结构在一个数组内,而不必设置整个结构.在下面的示例中,我想在数组中设置元素543的一个字段.我不想复制整个元素(因为复制MassiveStruct会损害性能).
class P
{
struct S
{
public int a;
public MassiveStruct b;
}
void f(ref S s)
{
s.a = 3;
}
public static void Main()
{
S[] s = new S[1000];
f(ref s[543]); // Error: An object reference is required for the non-static field, method, or property
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在C#中做到这一点?或者我总是要从数组中复制整个结构,修改副本,然后将修改后的副本放回到数组中.
如何myStruct.myField使用DynamicMethod进行反射,将值设置为struct字段?当我调用setter(myStruct, 111)value时没有设置,因为MyStruct是值类型.Console.WriteLine(myStruct.myField)显示值3.
如何修改GetDelegate方法将值设置为myStruct.myField?
public struct MyStruct
{
public int myField;
}
public delegate void SetHandler(object source, object value);
private static SetHandler GetDelegate(Type type, FieldInfo fieldInfo)
{
DynamicMethod dm = new DynamicMethod("setter", typeof(void), new Type[] { typeof(object), typeof(object) }, type, true);
ILGenerator setGenerator = dm.GetILGenerator();
setGenerator.Emit(OpCodes.Ldarg_0);
setGenerator.DeclareLocal(type);
setGenerator.Emit(OpCodes.Unbox_Any, type);
setGenerator.Emit(OpCodes.Stloc_0);
setGenerator.Emit(OpCodes.Ldloca_S, 0);
setGenerator.Emit(OpCodes.Ldarg_1);
setGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
setGenerator.Emit(OpCodes.Stfld, fieldInfo);
setGenerator.Emit(OpCodes.Ldloc, 0);
setGenerator.Emit(OpCodes.Box, type);
setGenerator.Emit(OpCodes.Ret);
return (SetHandler)dm.CreateDelegate(typeof(SetHandler));
}
MyStruct myStruct = new …Run Code Online (Sandbox Code Playgroud) 我想假设这个问题的目的是检查是否至少有一种方法,即使通过最不安全的黑客,仍然保持对非blittable值类型的引用.我知道这种设计类型与犯罪相当; 除了学习之外,我不会在任何实际案例中使用它.因此,请接受现在阅读异常不安全的代码.
我们知道可以以这种方式存储和增加对blittable类型的引用:
unsafe class Foo
{
void* _ptr;
public void Fix(ref int value)
{
fixed (void* ptr = &value) _ptr = ptr;
}
public void Increment()
{
var pointer = (int*) _ptr;
(*pointer)++;
}
}
Run Code Online (Sandbox Code Playgroud)
在安全性方面,上述类别可以与虚空中的跳跃相媲美(没有双关语意),但正如这里已经提到的那样.如果在堆栈上分配的变量传递给它,然后调用方法的作用域终止,则可能会遇到错误或显式访问冲突错误.但是,如果您执行这样的程序:
static class Program
{
static int _fieldValue = 42;
public static void Main(string[] args)
{
var foo = new Foo();
foo.Fix(ref _fieldValue);
foo.Increment();
}
}
Run Code Online (Sandbox Code Playgroud)
在卸载相关应用程序域之前,不会处理该类,因此适用于该字段.老实说,我不知道高频堆中的字段是否可以重新分配,但我个人认为不是.但是现在让我们放弃安全(如果可能的话).在阅读了这个和这些问题后,我想知道是否有办法为非blittable静态类型创建类似的方法,所以我制作了这个程序,它实际上有效.阅读评论以了解它的作用.
static class Program
{
static Action _event;
public static …Run Code Online (Sandbox Code Playgroud) 黑板是在运行时存储和获取通用键值对的对象.它可以通过a实现Dictionary<object,object>.有些子系统写入黑板,让其他子系统从中读取.
存储黑板的系统不知道其中包含什么类型的对象,何时.特定密钥的编写者和读者总是知道并同意键值对的类型.为了便于实现,牺牲了编译时检查 - 有许多编写器和读者,并且它们不断被迭代.
我的黑板界面如下所示:
interface Blackboard {
bool HasKey(object key);
T GetValue<T>(object key);
}
Run Code Online (Sandbox Code Playgroud)
作家创建并返回黑板,因此SetValue(key, value)可以是实现细节.
我最初的实现使用Dictionary<object,object>,一切都很好.但是,这块黑板必须快速且无需分配.这是不容谈判的.如果一个编写器将一个浮动值推入黑板,那么天真的实现就会将int放入字典中.
我不能在实现类上使用泛型类型BlackboardImpl<ValueType> : Blackboard,因为值类型在黑板上不是常量.
我可以使用多个内部词典,Dictionary<object,float>,Dictionary<object,int>等有后备Dictionary<object,object>,很多的SetValue功能,所以现在我不上插盒.但是由于GetValue函数来自接口,我不能对它进行约束,所以我仍然在退出时装箱:
T GetValue<T>(object key) {
if (typeof(T) == typeof(int)) {
// return intStore[key]; // doesn't compile
return (T)(object)intStore[key]; // boxes, allocates, bad.
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
有没有我在这里缺少的语法技巧,包括改变黑板界面,避免拳击?任何反射黑客都会违反"快速"要求,即使您可以在没有分配的情况下实施它.
干杯.
FieldInfo我能够找到的文档没有比较和对比这两种方法。我有兴趣了解何时应该在另一个之上使用它(最好使用一个小的代码片段)。