简体   繁体   English

转换通用 Span<t> 到一个特定的实例化(例如 Span<int> ) 如果它在运行时实际上是那种类型</int></t>

[英]Converting a generic Span<T> to a specific instantiation (e.g. Span<int>) if it actually of that type at runtime

Consider the following C# code:考虑以下 C# 代码:

using System;

public static class C
{
    public static int[] TryGetIntArray<T>(T[] x)
    {
        if (x is int[] arr) // ok
            return arr;

        return Array.Empty<int>();
    }

    public static Span<int> TryGetIntSpan<T>(Span<T> x)
    {
        if (x is Span<int> span) // An expression of type 'Span<T>' cannot be handled by a pattern of type 'Span<int>'.
            return span;

        return Span<int>.Empty;
    }
}

The idea is to return the argument as a particular specialization of Span<T> (in this case, Span<int> ) if the argument is actually of that type at runtime;这个想法是,如果参数在运行时实际上是该类型,则将参数返回为Span<T>的特定特化(在本例中为Span<int> ); otherwise, just return an empty span.否则,只返回一个空跨度。 We can see that this approach works with an array, but fails with a span.我们可以看到这种方法适用于数组,但不适用于跨度。 Is there a workaround to do this with spans as well?是否也有解决方法可以使用 span 来做到这一点?

If you can add where T: struct , there's a method for that:如果你可以添加where T: struct ,那么有一个方法:

public static Span<int> TryGetIntSpan<T>(Span<T> x)
    where T : struct
{
    if (typeof(T) == typeof(int))
        return MemoryMarshal.Cast<T, int>(x);

    return Span<int>.Empty;
}

Otherwise, here's another way:否则,这是另一种方式:

public static Span<int> TryGetIntSpan<T>(Span<T> x)
{
    if (typeof(T) == typeof(int))
        return MemoryMarshal.CreateSpan(ref Unsafe.As<T, int>(ref MemoryMarshal.GetReference(x)), x.Length);

    return Span<int>.Empty;
}

It deconstructs and reconstructs the span, as you can't just use Unsafe.As for this, since Span is a ref struct and therefore it's not usable as a type parameter.它解构和重建跨度,因为你不能只使用Unsafe.As 。至于这个,因为Span是一个ref结构,因此它不能用作类型参数。

The if (typeof(T) == typeof(int)) check is optimized away by the JIT. JIT 优化了if (typeof(T) == typeof(int))检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取通用类型对象(例如MyObject <T> )从远程机器 - Get generic type object (e.g. MyObject<T>) from remote machine 是否可以查找给定类型的所有名称别名(例如,“ int”与“ Int32”)? - Is it possible to look up all name alias of a given type (e.g. “int” versus “Int32”)? 无法将当前JSON数组(例如[1,2,3])反序列化为类型&#39;System.Collections.Generic.Dictionary - Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary 无法反序列化当前JSON对象(例如{“ name”:“ value”})为类型&#39;System.Collections.Generic.List - Cannot deserialize the current JSON object (e.g. {“name”:“value”}) into type 'System.Collections.Generic.List 无法将当前 JSON object(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1 - Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1 无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型&#39;System.Collections.Generic.List`1&#39; - Cannot deserialize the current JSON object (e.g. {“name”:“value”}) into type 'System.Collections.Generic.List`1' 类型名称为“ this”参数的扩展方法,例如int?.TryParse(“ 32”) - Extension methods with type name as `this` parameter, e.g. int?.TryParse(“32”) C#:找出代码中算术运算的结果类型(例如,int + double = double) - C#: Find out result type of arithmetic operations in code (e.g. int + double = double) 当值相同但类型不同时比较两个变量(例如Int16,Int32,Int64) - Comparing two variables when the value is the same but the type is different (e.g. Int16, Int32, Int64) 如何将 int 写入 System.Span,即 int.Parse(span) 的反转? - How to write an int into System.Span, i.e the revers of int.Parse(span)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM