首页 > 解决方案 > 为什么 T : IMyInterface 在 C# 中工作,但 IMyInterface 不工作?

问题描述

我一直在 C# 中尝试使用泛型来改进编写样板代码。

最近,我写了这个方法来重复一个分页的 REST API 调用,直到页面用完。该方法假定对象遵循一个IPaginated接口,该接口只有一个必需的 ID 属性。

这是我最初的实现。


        /// <summary>
        /// Generic implementation of getting all object from a paginated API call.
        /// </summary>
        /// <param name="getTask">Delegate to the API calling method, points to the last object ID or null.</param>
        /// <param name="limit">The limit on # of elements.</param>
        /// <returns></returns>
        internal static async Task<Models.IPaginated[]> GetPaginated(Func<string, Task<Models.IPaginated[]>> getTask, int limit)
        {
            List<Models.IPaginated> values = new List<Models.IPaginated>();
            Models.IPaginated[] page = await getTask(null);
            values.AddRange(page);

            while (page.Length == limit)
            {
                var lastobj = page[limit - 1];
                page = await getTask(lastobj.ID);
                values.AddRange(page);
            }

            return values.ToArray();
        }

但是,当我写出委托对象时,这会导致编译器错误。(A 类实现 IPaginated。)


        public async Task<Models.ClassA[]> GetAll(string arg1, string arg2)
        {
            int limit = 100;
            Func<string, Task<Models.ClassA[]>> getTask = ((string lastobj) =>
            {
                return Get(arg1, arg2, limit, lastobj);
            });

            return await GetPaginated(getTask, limit);
        }

所以,现在我将方法重新设计为一个由IPaginated.

        /// <summary>
        /// Generic implementation of getting all object from a paginated API call.
        /// </summary>
        /// <param name="getTask">Delegate to the API calling method, points to the last object ID or null.</param>
        /// <param name="limit">The limit on # of elements.</param>
        /// <returns></returns>
        internal static async Task<T[]> GetPaginated<T>(Func<string, Task<T[]>> getTask, int limit)
            where T : Models.IPaginated
        {
            List<T> values = new List<T>();
            T[] page = await getTask(null);
            values.AddRange(page);

            while (page.Length == limit)
            {
                var lastobj = page[limit - 1];
                page = await getTask(lastobj.ID);
                values.AddRange(page);
            }

            return values.ToArray();
        }

这不会导致编译器错误。但为什么?以及如何 T : IPaginated 允许我在不强制转换对象的情况下检索 .ID 属性?

标签: c#

解决方案


推荐阅读