0

如果问题措辞不佳,我深表歉意,这是一个很难表达或寻找答案的问题,并且将“in”关键字用于逆变代表也无济于事。这是我可以描述它的最佳方式:

设置:

public delegate int TComparer(in T left, in T right);

// an instance of the delegate, initialized elsewhere
private TComparer _comparer;

// an array of T, initialized elsewhere
private T[] data;

'in' 关键字意味着这些操作会引发转换错误:

Array.Sort(data, _comparer); // CS1503

Func<T,T,int> _func = _comparer; // CS1503

因为参数使用'in'关键字的函数与不使用'in'关键字的函数不同,所以在我看来,没有任何方法可以以这种方式将委托(或IComparer等)与关键字一起使用。库中是否有旨在处理这些情况的东西,或者在更具体的情况下是否有另一种方法可以获得相同的效率*?

(* 注意:在这种情况下,T 可能是一个巨大的不可变结构,大量存在并且被频繁访问,因此避免防御性复制非常有用。)

编辑:这是对代码的更完整的了解:

public readonly struct QuadData {

    public readonly VertexPositionColorTexture TL; // 6 floats in a struct
    public readonly VertexPositionColorTexture TR; 
    public readonly VertexPositionColorTexture BL;
    public readonly VertexPositionColorTexture BR;
    public readonly int Depth;
    public readonly int TextureCode;

    // constructors...
}

public class SpriteBatcher {

    public SpriteBatcher() {
        _quadBuffer = Array.Empty<QuadData>();
        _quadComparer = CompareByDepthDescendingThenTexture;

    }

    public delegate int QuadDataComparer(in QuadData left, in QuadData right);

    private QuadDataComparer _quadDataComparer; // initialized in constructor

    private QuadData[] _quadBuffer; // initialized in constructor

    public void Update() {
        Array.Sort(_quadBuffer, _quadDataComparer); // CS1503
    }
}

我认为一些额外的东西不能说明问题本身:

        private void OnSetSortingMode(SpriteSortOption sortOption) {

            if (sortOption == _sortOption) return;
            switch (sortOption) {
                case SpriteSortOption.None:
                    break;
                case SpriteSortOption.Texture:
                    _quadDataComparer = CompareByTexture;
                    break;
                case SpriteSortOption.DepthAscending:
                    _quadDataComparer = CompareByDepthAscendingThenTexture;
                    break;
                case SpriteSortOption.DepthDescending:
                    _quadDataComparer = CompareByDepthDescendingThenTexture;
                    break;
                default:
                    throw new ArgumentException($"Unimplemented SpriteBatcher.SortOptions enumerated value {sortOption} passed to SpriteBatcher.SetSortingMode()");
                }
            if (sortOption != SpriteSortOption.None) {
                _flags |= SpriteBatcherFlags.Sort;
                }
            }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private int CompareByTexture(in QuadData x, in QuadData y) {
            return y.TextureHashCode - x.TextureHashCode; // int.CompareTo(int) is not needed because we don't actually care if a HashCode is larger or smaller, only different.
            }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private int CompareByDepthAscendingThenTexture(in QuadData x, in QuadData y) {
            if (x.Depth < y.Depth) return 1;
            if (x.Depth > y.Depth) return -1;
            return y.TextureHashCode - x.TextureHashCode; // int.CompareTo(int) is not needed because we don't actually care if a HashCode is larger or smaller, only different.
            }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private int CompareByDepthDescendingThenTexture(in QuadData x, in QuadData y) {
            if (x.Depth > y.Depth) return 1;
            if (x.Depth < y.Depth) return -1;
            return y.TextureHashCode - x.TextureHashCode; // int.CompareTo(int) is not needed because we don't actually care if a HashCode is larger or smaller, only different.
            }

        public void SetCustomSortOption(QuadDataComparer comparison) {
            this._quadDataComparer = comparison;
            this._sortOption = SpriteSortOption.Custom;
            }
4

0 回答 0