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

C# is类型判断时能否为两个派生类使用同名模式变量

问题场景

首先定义了基础接口IKlarfDefect:

public interface IKlarfDefect
{
    int TEST { get; set; }
    int DEFECTID { get; set; }
}

基于该接口派生两个实现类(注:原示例代码存在笔误,重复声明了IKlarfDefect接口,以下为修正后的结构):

public class RMTKlarfDefect : IKlarfDefect
{
    public int TEST { get; set; }
    public int DEFECTID { get; set; }
    public List<RMTKlarfImageListInfo> KlarfImageList { get; set; } = new List<RMTKlarfImageListInfo>();
}

public class CIMKlarfDefect : IKlarfDefect
{
    public int TEST { get; set; }
    public int DEFECTID { get; set; }
    public List<CIMKlarfImageListInfo> KlarfImageList { get; set; } = new List<CIMKlarfImageListInfo>();
}

编写遍历IKlarfDefect集合的方法时,尝试在is类型判断中给两种派生类的匹配结果使用同一个变量名klarfDefectGeneric:

internal static string CreateDefectListString(IEnumerable<IKlarfDefect> klarfDefectList)
{
    StringBuilder defectListString = new StringBuilder();
    defectListString.AppendLine("");
    foreach (var klarfDefect in klarfDefectList)
    {    
        if ((klarfDefect is CIMKlarfDefect klarfDefectGeneric || klarfDefect is RMTKlarfDefect klarfDefectGeneric) ) 
        {
            if (klarfDefectGeneric.KlarfImageList.Count == 0)
            {
                defectListString.Append("N;");
                defectListString.AppendLine();
            }
        }
    }
}

编译时抛出如下错误:

Error CS0128 A local variable or function named 'klarfDefectGeneric' is already defined in this scope

问题原因

C# 8.0及更早版本不允许在同一个||逻辑判断的不同is模式匹配分支中声明同名变量,两个klarfDefectGeneric变量同属一个方法作用域,编译器会判定为重复定义。
另外原示例代码除了接口重复定义的笔误外,还存在两个问题:方法签名要求返回string但代码中没有返回语句、两种实现类的KlarfImageList属性是不同泛型类型,没有在基础接口中声明,无法通过IKlarfDefect类型的变量直接访问。

可行解决方案

方案1:升级C# 9.0+使用or模式匹配

C# 9.0开始新增类型联合的or模式,支持在同一模式判断中为不同类型的匹配结果声明同名变量,直接修改if判断条件即可:

if (klarfDefect is CIMKlarfDefect klarfDefectGeneric or RMTKlarfDefect klarfDefectGeneric)
{
    if (klarfDefectGeneric.KlarfImageList.Count == 0)
    {
        defectListString.Append("N;");
        defectListString.AppendLine();
    }
}

注意:由于两个实现类的KlarfImageList是不同泛型类型的集合,部分编译器配置下可能无法直接识别该公共属性,这种场景推荐使用方案2。

方案2:抽取公共成员到上层接口(推荐,兼容所有C#版本)

这是最符合面向对象设计原则的方案:把所有派生类共有的成员、判断逻辑抽到基础IKlarfDefect接口中,后续遍历不需要做类型判断,从根源避免类型转换问题:

// 基础接口定义所有公共成员
public interface IKlarfDefect
{
    int TEST { get; set; }
    int DEFECTID { get; set; }
    // 暴露需要用到的判断逻辑,隐藏具体的列表实现
    bool IsImageListEmpty { get; }
}

// RMT实现类
public class RMTKlarfDefect : IKlarfDefect
{
    public int TEST { get; set; }
    public int DEFECTID { get; set; }
    public List<RMTKlarfImageListInfo> KlarfImageList { get; set; } = new List<RMTKlarfImageListInfo>();
    public bool IsImageListEmpty => KlarfImageList.Count == 0;
}

// CIM实现类
public class CIMKlarfDefect : IKlarfDefect
{
    public int TEST { get; set; }
    public int DEFECTID { get; set; }
    public List<CIMKlarfImageListInfo> KlarfImageList { get; set; } = new List<CIMKlarfImageListInfo>();
    public bool IsImageListEmpty => KlarfImageList.Count == 0;
}

修改后遍历方法可简化为:

internal static string CreateDefectListString(IEnumerable<IKlarfDefect> klarfDefectList)
{
    StringBuilder defectListString = new StringBuilder();
    defectListString.AppendLine("");
    foreach (var klarfDefect in klarfDefectList)
    {    
        if (klarfDefect.IsImageListEmpty)
        {
            defectListString.Append("N;");
            defectListString.AppendLine();
        }
    }
    // 补全缺失的返回逻辑
    return defectListString.ToString();
}

方案3:低版本C#兼容写法

如果暂时不能升级C#版本、也不方便重构接口,可以分开做类型判断,提取公共逻辑避免同名变量冲突:

foreach (var klarfDefect in klarfDefectList)
{
    bool isEmpty = false;
    if (klarfDefect is CIMKlarfDefect cimDefect)
    {
        isEmpty = cimDefect.KlarfImageList.Count == 0;
    }
    else if (klarfDefect is RMTKlarfDefect rmtDefect)
    {
        isEmpty = rmtDefect.KlarfImageList.Count == 0;
    }

    if (isEmpty)
    {
        defectListString.Append("N;");
        defectListString.AppendLine();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 01:12:28