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

PowerShell自定义类实现未赋值属性隐藏及-Force显示需求

实现动态属性可见性的Package类

纯PowerShell类无法直接实现「未赋值属性默认隐藏、赋值后显示、-Force强制显示」的逻辑,因此用C#通过Add-Type来实现,同时保留字符串引用返回Name的行为。

完整代码

Add-Type @"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Management.Automation;

public class Package : ICustomTypeDescriptor {
    public string Name { get; set; }
    public string Latest { get; set; }
    public string Prerelease { get; set; }

    public override string ToString() {
        return this.Name;
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() {
        return GetProperties(false);
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) {
        bool force = false;
        foreach (Attribute attr in attributes) {
            if (attr is PSPropertyInfoAttribute psAttr && psAttr.Force) {
                force = true;
                break;
            }
        }
        return GetProperties(force);
    }

    private PropertyDescriptorCollection GetProperties(bool force) {
        var props = new List<PropertyDescriptor>();
        props.Add(TypeDescriptor.GetProperties(this)["Name"]);
        props.Add(TypeDescriptor.GetProperties(this)["Latest"]);
        
        if (force || Prerelease != null) {
            props.Add(TypeDescriptor.GetProperties(this)["Prerelease"]);
        }
        return new PropertyDescriptorCollection(props.ToArray());
    }

    // 以下为ICustomTypeDescriptor接口的默认实现,无需修改
    AttributeCollection ICustomTypeDescriptor.GetAttributes() => TypeDescriptor.GetAttributes(this);
    string ICustomTypeDescriptor.GetClassName() => TypeDescriptor.GetClassName(this);
    string ICustomTypeDescriptor.GetComponentName() => TypeDescriptor.GetComponentName(this);
    TypeConverter ICustomTypeDescriptor.GetConverter() => TypeDescriptor.GetConverter(this);
    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this);
    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this);
    object ICustomTypeDescriptor.GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType);
    EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => TypeDescriptor.GetEvents(this);
    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes);
    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) => this;
}
"@

# 测试示例
$test = [Package]::new()
$test.Name = 'Example'
$test.Latest = '0.1'

Write-Host "=== 默认输出(Prerelease未赋值,隐藏) ==="
$test | Format-Table

Write-Host "`n=== 赋值Prerelease后输出(显示属性) ==="
$test.Prerelease = '0.1-beta'
$test | Format-Table

Write-Host "`n=== -Force强制输出(无论赋值状态都显示) ==="
$test.Prerelease = $null
$test | Format-Table -Force

Write-Host "`n=== 字符串引用输出(返回Name) ==="
"$test"

逻辑说明

  • 通过实现ICustomTypeDescriptor接口,接管属性枚举逻辑:
    • 默认模式下,仅返回Name和Latest属性;当Prerelease被赋值(非null)时,才将其加入属性列表
    • 检测到-Force参数时(通过PSPropertyInfoAttribute.Force标识),强制包含Prerelease属性,无论是否赋值
  • 重写ToString()方法,确保字符串插值(如"$test")时返回Name值
  • 其余接口方法使用默认实现,保证对象的常规行为不受影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:17:33