You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个方法中兼容传入Product或Category类型对象?

解决方案

针对你需要让日志方法兼容Product和Category两种类型的场景,因为二者属性结构完全一致,可以通过以下几种方式实现:

方法一:定义公共接口(推荐方案)

通过抽象公共属性结构来实现多态复用,这是类型安全且性能最优的方式:

  1. 先定义一个包含公共属性的接口:
public interface IHasContentImages
{
    // 这里的类型要和你的CategoryImages实际类型匹配
    ImageCollection CategoryImages { get; }
}

// 补充对应的依赖类型定义(根据你的实际代码调整)
public class ImageCollection
{
    public List<ImageItem> Items { get; set; }
}

public class ImageItem
{
    public ContentLink ContentLink { get; set; }
}

public class ContentLink
{
    public Guid ID { get; set; }
    public string ProviderName { get; set; }
    public bool GetPublishedOrLatest { get; set; }
}
  1. 让Product和Category类实现这个接口:
public class Product : IHasContentImages
{
    public ImageCollection CategoryImages { get; set; }
    // 其他Product专属属性
}

public class Category : IHasContentImages
{
    public ImageCollection CategoryImages { get; set; }
    // 其他Category专属属性
}
  1. 修改日志方法,接收接口类型参数:
public void LogContentLinkInformation(IHasContentImages itemWithImages)
{
    // 提前判空避免空引用
    if (itemWithImages?.CategoryImages?.Items == null)
        return;

    foreach (var imageItem in itemWithImages.CategoryImages.Items)
    {
        var contentLink = imageItem.ContentLink;
        if (contentLink == null)
            continue;

        _logger.LogDebug(nameof(ProcessFiles), $"Content Link Id: {contentLink.ID.ToString()}");
        _logger.LogDebug(nameof(ProcessFiles), $"Provider Name: {contentLink.ProviderName}");
        _logger.LogDebug(nameof(ProcessFiles), $"GetPublishedOrLatest: {contentLink.GetPublishedOrLatest.ToString()}");
    }
}

调用时直接传入Product或Category对象即可:

var product = new Product();
LogContentLinkInformation(product);

var category = new Category();
LogContentLinkInformation(category);

方法二:泛型+反射(适用于无法修改原有类的场景)

如果你不能修改Product和Category的源代码,无法让它们实现接口,可以用反射来读取公共属性:

public void LogContentLinkInformation<T>(T item)
{
    if (item == null)
        return;

    // 反射获取CategoryImages属性
    var categoryImagesProp = typeof(T).GetProperty(nameof(Category.CategoryImages));
    if (categoryImagesProp == null)
        return;

    var categoryImages = categoryImagesProp.GetValue(item);
    if (categoryImages == null)
        return;

    // 获取Items集合
    var itemsProp = categoryImages.GetType().GetProperty(nameof(ImageCollection.Items));
    if (itemsProp == null)
        return;

    var items = itemsProp.GetValue(categoryImages) as IEnumerable;
    if (items == null)
        return;

    foreach (var imageItem in items)
    {
        if (imageItem == null)
            continue;

        // 获取ContentLink属性
        var contentLinkProp = imageItem.GetType().GetProperty(nameof(ImageItem.ContentLink));
        if (contentLinkProp == null)
            continue;

        var contentLink = contentLinkProp.GetValue(imageItem);
        if (contentLink == null)
            continue;

        // 读取并日志ContentLink的各个属性
        var idProp = contentLink.GetType().GetProperty(nameof(ContentLink.ID));
        var providerNameProp = contentLink.GetType().GetProperty(nameof(ContentLink.ProviderName));
        var getPublishedProp = contentLink.GetType().GetProperty(nameof(ContentLink.GetPublishedOrLatest));

        if (idProp != null)
            _logger.LogDebug(nameof(ProcessFiles), $"Content Link Id: {idProp.GetValue(contentLink)?.ToString()}");
        if (providerNameProp != null)
            _logger.LogDebug(nameof(ProcessFiles), $"Provider Name: {providerNameProp.GetValue(contentLink)}");
        if (getPublishedProp != null)
            _logger.LogDebug(nameof(ProcessFiles), $"GetPublishedOrLatest: {getPublishedProp.GetValue(contentLink)?.ToString()}");
    }
}

注意:反射会有一定性能损耗,高频调用场景不建议用。

方法三:动态类型(简单但无编译检查)

这种方式最简洁,但失去了编译时类型校验,一旦属性名变更会导致运行时错误:

public void LogContentLinkInformation(dynamic item)
{
    if (item?.CategoryImages?.Items == null)
        return;

    foreach (var imageItem in item.CategoryImages.Items)
    {
        var contentLink = imageItem.ContentLink;
        if (contentLink == null)
            continue;

        _logger.LogDebug(nameof(ProcessFiles), $"Content Link Id: {contentLink.ID.ToString()}");
        _logger.LogDebug(nameof(ProcessFiles), $"Provider Name: {contentLink.ProviderName}");
        _logger.LogDebug(nameof(ProcessFiles), $"GetPublishedOrLatest: {contentLink.GetPublishedOrLatest.ToString()}");
    }
}

调用时直接传两种类型对象即可,但开发阶段无法提前发现属性不匹配的问题。


内容的提问来源于stack exchange,提问作者S92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:32:46