【问题标题】:It is possible to initialize a Span<T> field in a ref struct?可以在 ref 结构中初始化 Span<T> 字段吗?
【发布时间】:2021-06-18 07:31:29
【问题描述】:

这不起作用,因为您不能直接初始化结构中的字段:

public ref  struct WordCollection
    {     
        public Span<byte> words = stackalloc byte[100];
    }

错误是:“WordCollection”:结构中不能有实例属性或字段初始值设定项。

但是,我也无法使用构造函数对其进行初始化:

public ref  struct WordCollection
    {     
        public Span<byte> words;

        public WordCollection(int size)
        {
            words = stackalloc byte[size];
        }
    }

这里的错误是:在将控制权返回给调用者之前,必须完全分配字段“WordCollection.words”。

这也行不通:

public ref  struct WordCollection
    {     
        public Span<byte> words;
    }

public class Test
    {
       public static void WordProc()
        {
            WordCollection wordCollection = new WordCollection();
            wordCollection.words = stackalloc byte[100];
        } 
    }

错误是:'Span' 类型的 stackalloc 表达式的结果不能在此上下文中使用,因为它可能暴露在包含方法之外。

那么,问题是:可以初始化一个引用结构的Span&lt;T&gt; 字段吗?

【问题讨论】:

  • 我看到的中间代码错误与您在此处引用的完全不同。
  • because it may be exposed outside of the containing method. 从字面上告诉你问题:你不能在结构的构造中的任何地方stackalloc 因为一旦你返回调用者它就会消失(它是一个 stack毕竟分配)@JonSkeet 在他的回答中是正确的,你必须从调用者方法传递Span
  • 有趣的是,编译器允许new WordCollection { words = stackalloc byte[100] },这似乎不一致。至少,对象初始值设定项的定义中没有任何内容可以解释为什么在不允许单独赋值的情况下允许这样做。

标签: c# memory struct


【解决方案1】:

这可能不是最好的方法,但您可以将 Span&lt;byte&gt; 传递给构造函数:

public ref struct WordCollection
{
    public Span<byte> words;

    public WordCollection(Span<byte> words)
    {
        this.words = words;
    }
}

然后:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
        WordCollection words = new WordCollection(stackalloc byte[100]);
    }
}

这真的取决于你想用它做什么......

【讨论】:

  • 只是想:为什么案例 #3 不起作用?它被声明为ref struct,所以编译器知道它不会逃跑
  • @Charlieface:恐怕这个的微妙之处超出了我的范围。我一直觉得ref struct 部分很难理解:(
【解决方案2】:

我发现这是可行的:

public ref  struct WordCollection
    {     
        public Span<byte> words;
    }

public class Test
    {
       public static void WordProc()
        {
            WordCollection wordCollection = new WordCollection {
                wordCollection.words = stackalloc byte[100]
            };
        } 
    }

这有点奇怪,不是我喜欢的方式,但可以完成工作。

【讨论】:

  • 这不能编译; wordCollection.words 在初始化程序中使用是不合法的。只是words 是。
猜你喜欢
  • 2020-12-07
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多