小编Mic*_*l B的帖子

为什么拆箱枚举会产生奇怪的结果?

考虑以下::

Object box = 5;
int @int = (int)box;  // int = 5
int? nullableInt = box as int?; // nullableInt = 5;
StringComparison @enum = (StringComparison)box; // enum = OrdinalIgnoreCase
StringComparison? nullableEnum = box as StringComparison?; // nullableEnum = null.
Run Code Online (Sandbox Code Playgroud)

2件事::

  1. 为什么我可以拆箱StringComparison?我想这是因为它的底层类型是,Int32但我仍然觉得它很奇怪.
  2. 为什么nullableEnum值为null?

据我所知,唯一有效的拆箱是从盒装值类型到它的类型或可空类型.如果int可以取消装箱Enum,那么为什么不能同样适用于可空值?同样,如果不是5我装盒StringComparison.OrdinalIgnoreCase,那nullableInt将是null,但nullableEnum不会.

c# enums unboxing

7
推荐指数
1
解决办法
945
查看次数

使用LINQ获取接口Type []上的所有方法?

我试图通过反射找到界面授予我的所有方法.我有一个类型数组,我验证只有接口,从那里我需要提取所有方法.不幸的是,如果我做类似的事情(IList).GetMethods()它只返回IList上的方法而不是ICollection上的方法,或者IEnumerable我尝试了以下linq查询,但它不返回外部接口上找到的方法.如何修复查询?

from outerInterfaces in interfaces
from i in outerInterfaces.GetInterfaces()   
from m in i.GetMethods()
select m
Run Code Online (Sandbox Code Playgroud)

如果这是SQL,我可以做一些类似于带有union all的递归CTE,但我不认为C#中存在这样的语法.有人可以帮忙吗?

c# linq

6
推荐指数
1
解决办法
852
查看次数

为什么添加beforefieldinit会大大提高泛型类的执行速度?

我正在研究代理和带有引用类型参数的泛型类,它非常慢.特别是对于通用方法(对于刚刚返回null的普通泛型方法,大约400毫秒对3200毫秒).我决定尝试看看如果我在C#中重写生成的类,它会如何执行,并且它表现得更好,与非泛型类代码的性能相同.

这是我写的C#类::(注意我通过命名方案改变但不是很多)::

namespace TestData
{
    public class TestClassProxy<pR> : TestClass<pR>
    {
        private InvocationHandler<Func<TestClass<pR>, object>> _0_Test;
        private InvocationHandler<Func<TestClass<pR>, pR, GenericToken, object>> _1_Test;
        private static readonly InvocationHandler[] _proxy_handlers = new InvocationHandler[] { 
            new InvocationHandler<Func<TestClass<pR>, object>>(new Func<TestClass<pR>, object>(TestClassProxy<pR>.s_0_Test)), 
        new GenericInvocationHandler<Func<TestClass<pR>, pR, GenericToken, object>>(typeof(TestClassProxy<pR>), "s_1_Test") };



        public TestClassProxy(InvocationHandler[] handlers)
        {
            if (handlers == null)
            {
                throw new ArgumentNullException("handlers");
            }
            if (handlers.Length != 2)
            {
                throw new ArgumentException("Handlers needs to be an array of 2 parameters.", "handlers");
            }
            this._0_Test = (InvocationHandler<Func<TestClass<pR>, object>>)(handlers[0] ?? _proxy_handlers[0]);
            this._1_Test …
Run Code Online (Sandbox Code Playgroud)

c# il cil reflection.emit

6
推荐指数
1
解决办法
1421
查看次数

通过动态方法解析IL中发现的令牌

感谢Hans Passant在这里回答我的问题: 如何从DynamicMethod获取IL bytearray?

我能够起床和跑步.我现在正在尝试解决在IL发出的元数据令牌,以查看正在调用哪些方法,或者什么不是.我能够解决方法体中的下一个标记是一个调用.我正在使用来自Mono.ReflectionMethodBodyReader的一些代码.

static byte[] GetILByteArray(Delegate @delegate){
   // does stuff mentioned in other thread
}
...
Expression<Action> foo = () => Console.WriteLine(0);
var compiled = foo.Compile();
var bytes = GetILByteArray(compiled);
int index =Array.FindIndex(bytes,b=>GetOpCode(b).OperandType == OperandType.InlineMethod);
var token = BitConverter.ToInt32(bytes,index+1);
compiled.Method.Module.ResolveMember(token);
Run Code Online (Sandbox Code Playgroud)

引发异常,说明该域中的令牌是不可解析的.这里有人有诀窍吗?我应该尝试传递代理通用参数还是完全没用?

我现在正在考虑为表达式树的代表编写一个反编译器的想法,我真的希望能够使用我自己编译为测试用例的表达式树,因为我总是可以回到原始版本并进行比较.

c# dynamicmethod

5
推荐指数
1
解决办法
1215
查看次数

如何从struct的实例方法创建一个开放的Delegate?

我有一个带有私有方法的结构,我想调用它.由于我计划在性能关键部分执行此操作,因此我想缓存一个委托来执行操作.问题是我似乎无法使用Delegate.CreateDelegate绑定到它的方法.有问题的结构不是我的创建,用于与第三方库的交互.有问题的结构看起来像这样::

public struct A
{
     private int SomeMethod()
     {
        //body go here
     }
}
Run Code Online (Sandbox Code Playgroud)

以下代码将失败,并出现"绑定到目标方法的错误".

Delegate.CreateDelegate(typeof(Func<A,int>),typeof(A).GetMethod("SomeMethod",BindingFlags.Instance | BindingFlags.NonPublic));
Run Code Online (Sandbox Code Playgroud)

我知道我可以写一个表达式树来执行动作,但似乎很奇怪,我不能使用我的正常goto这些Delegate.CreateDelegate方法.

如果A是一个类,上面的代码工作得很好.这个问题只是因为A结构而产生的.MSDN文档对于CreateDelegate的这个重载是不正确的,因为它对非静态方法起作用.

c# delegates

5
推荐指数
1
解决办法
1870
查看次数

Delegate.CreateDelegate无法绑定到struct member覆盖的错误是什么?

在回答了这个问题后,我发现我必须使用一个ref参数来调用结构上的实例方法. 如何从struct的实例方法创建一个开放的Delegate?

我似乎无法绑定到显式接口实现之类的方法覆盖(以避免相关的拳击惩罚,(就IL而言,这实际上是覆盖的)),这是一个错误报告,说明在.NET的未来版本中,我们可以绑定到结构上的接口成员:https: //connect.microsoft.com/VisualStudio/feedback/details/574959/cannot-create-open-instance-delegate-for-value-types-methods-which-implement -an接口?WA = wsignin1.0#细节

但是,即使试图绑定到相同的部件Equals,GetHashCodeToString导致错误的发生如

public struct A
{
     public override int GetHashCode(){/*implementation goes here*/}
}
delegate TRet FuncByRef<TStruct,TRet>(ref TStruct) where TStruct:struct
Run Code Online (Sandbox Code Playgroud)

...

Delegate.CreateDelegate(typeof(FuncByRef<A,int>),typeof(A).GetMethod("GetHashCode"));
Run Code Online (Sandbox Code Playgroud)

将失败,并出现"绑定到目标方法时出错"的异常.

c# delegates

5
推荐指数
1
解决办法
591
查看次数

如何进入使用DebuggerStepThroughAttribute修饰的方法?

我想避免调试器进入一系列可能导致异常的验证辅助方法,如果抛出异常,我希望它出现在调用点,而不是在这些辅助方法中.所以我将DebuggerStepThroughAttribute放在辅助方法上.但是,由于验证方法可能存在错误,我仍然希望能够调试验证方法.如果我在其中一个验证方法中放置一个断点,调试器仍然会跳过它.

我如何得到它,以便抛出异常时跳过方法,但如果我在方法中放置一个断点,那么我应该能够进入它,或者这是不可能的?

c# debugging

5
推荐指数
1
解决办法
270
查看次数

如何消除此循环向量化的数组绑定检查?

我有一项任务是从二进制文字0x0上的数据库表中拆分多行varbinary(8000)列.但是,这可能会改变,所以我想保留这个变量.我想使用SQLCLR作为流表值函数快速执行此操作.我知道我的字符串总是至少有几千字节.

编辑:我已经更新了我的算法.为了避免内环展开的肮脏.但很难说服CLR对寄存器分配做出正确的选择.如果有一个简单的方法来说服CLR j和我真的是同一件事,那将是非常棒的.但相反,它确实是愚蠢的事情.优化第一个路径循环会很不错.但你不能使用goto进入循环.

我决定改编C函数memchr的64位实现.基本上不是一次扫描一个字节并进行比较,而是使用一些比特来一次扫描8个字节.作为参考,Array.IndexOf<Byte>对于一个答案执行与4字节扫描类似的操作,我只想继续这样做.有几点需要注意:

  1. 内存压力是SQLCLR功能中的一个非常现实的问题.String.Split因为它预先分配了很多我真正想避免的内存.它也适用于UCS-2字符串,这需要我将我的ascii字符串转换为unicode字符串,因此在返回时将我的数据视为lob数据类型.(SqlChars/ SqlString在转换为lob类型之前只能返回4000个字节).

  2. 我想流.避免String.Split它的另一个原因是同时完成其工作,造成大量内存压力.在具有大量分隔符的代码上,纯T-SQL方法将开始击败它.

  3. 我想保持它"安全".所以都管理好了.在安全检查中似乎有很大的惩罚.

Buffer.BlockCopy真的很快,而且比不断支付BitConverter的成本似乎更好地支付前一次成本.这仍然比将我的输入转换为字符串并保持该引用更便宜.

代码非常快,但似乎我在初始循环和关键部分支付了相当多的绑定检查,当我找到匹配时.作为具有大量分隔符的代码的结果,我倾向于输入一个更简单的C#枚举器,它只进行字节比较.

这是我的代码,

class SplitBytesEnumeratorA : IEnumerator
{
    // Fields
    private readonly byte[] _bytes;
    private readonly ulong[] _longs;
    private readonly ulong _comparer;
    private readonly Record _record = new Record();
    private int _start;
    private readonly int _length;

    // Methods
    internal SplitBytesEnumeratorA(byte[] bytes, byte delimiter)
    {
        this._bytes = bytes;
        this._length = bytes.Length;
        // we do this so that we can avoid a spillover scan …
Run Code Online (Sandbox Code Playgroud)

c# arrays clr performance sqlclr

5
推荐指数
1
解决办法
502
查看次数

处理阵列时我应该固定什么?

我正在尝试编写一个DynamicMethod来包装cpblk IL 操作码。我需要在 x64 平台上复制字节数组块,这应该是最快的方法。Array.CopyBuffer.BlockCopy这两个工作,但我想探索的所有选项。

我的目标是将托管内存从一个字节数组复制到一个新的托管字节数组。我关心的是我如何知道如何正确“固定”内存位置。我不希望垃圾收集器移动数组并破坏所有内容。到目前为止它有效,但我不确定如何测试这是否是 GC 安全的。

// copying 'count' bytes from offset 'index' in 'source' to offset 0 in 'target'
// i.e. void _copy(byte[] source, int index, int count, byte[] target)

static Action<byte[], int, int, byte[]> Init()
{
    var dmethod = new DynamicMethod("copy", typeof(void), new[] { typeof(object),typeof(byte[]), typeof(int), typeof(int),typeof(byte[]) },typeof(object), true);
    var il = dmethod.GetILGenerator();

    il.DeclareLocal(typeof(byte).MakeByRefType(), true);
    il.DeclareLocal(typeof(byte).MakeByRefType(), true);
    // pin the source
    il.Emit(OpCodes.Ldarg_1);
    il.Emit(OpCodes.Ldarg_2);
    il.Emit(OpCodes.Ldelema, typeof(byte));
    il.Emit(OpCodes.Stloc_0);
    // pin …
Run Code Online (Sandbox Code Playgroud)

clr cil reflection.emit

5
推荐指数
1
解决办法
488
查看次数

如何替换表达式树中的类型参数?

我希望能够编写一个通用表达式,供用户用来描述他希望如何在一系列类型之间进行转换。

该表达式可能类似于:

Expression<Func<PlaceHolder,object>> sample = 
x=> (object)EqualityComparer<PlaceHolder>.GetHashCode(x)
Run Code Online (Sandbox Code Playgroud)

我想将其转换为:

Expression<Func<Foo,object>> sample = 
x=> (object)EqualityComparer<Foo>.GetHashCode(x)
Run Code Online (Sandbox Code Playgroud)

我可以只访问表达式,并PlaceHolder用x 替换参数,但随后我无法解析泛型调用。

该表达式是用户提供的,不能将通用方法分配给该表达式。

最终结果总是返回一个对象,而表达式始终是from T=>object。我将为默认规则将替换的任何对象编译一个新表达式。

这是我现有的有效代码,但看起来很复杂。

// ReSharper disable once InconsistentNaming
// By design this is supposed to look like a generic parameter.
public enum TEnum : long
{
}

internal sealed class EnumReplacer : ExpressionVisitor
{
    private Type ReplacePlaceHolder(Type type)
    {
        if (type.IsByRef)
        {
            return ReplacePlaceHolder(type.GetElementType()).MakeByRefType();
        }

        if (type.IsArray)
        {
            // expressionTrees can only deal with 1d arrays.
            return ReplacePlaceHolder(type.GetElementType()).MakeArrayType();
        }

        if (type.IsGenericType) …
Run Code Online (Sandbox Code Playgroud)

c# expression-trees

5
推荐指数
1
解决办法
748
查看次数