[fix]修正UdpServer在接收广播时连续启动接收的错误,在StarAgent中,此时可能收到广播包,SocketFlags是Broadcast,需要清空,否则报错“参考的对象类型不支持尝试的操作”; 无需设置SocketOptionName.PacketInformation,在ReceiveMessageFromAsync时会自动设置,并且支持ipv6;
石头 authored at 2024-10-10 00:36:00 石头 committed at 2024-10-10 00:45:43
2.30 KiB
X
using System.Dynamic;
using System.Globalization;
using System.Reflection;

namespace NewLife.Reflection;

/// <summary>包装程序集内部类的动态对象</summary>
public class DynamicInternal : DynamicObject
{
    private Object? Real { get; set; }

    /// <summary>类型转换</summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override Boolean TryConvert(ConvertBinder binder, out Object? result)
    {
        result = Real;

        return true;
    }

    /// <summary>成员取值</summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override Boolean TryGetMember(GetMemberBinder binder, out Object? result)
    {
        if (Real == null) throw new ArgumentNullException(nameof(Real));

        var property = Real.GetType().GetProperty(binder.Name, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
        if (property == null)
        {
            result = null;
        }
        else
        {
            result = property.GetValue(Real, null);
            if (result != null) result = Wrap(result);
        }
        return true;
    }

    /// <summary>调用成员</summary>
    /// <param name="binder"></param>
    /// <param name="args"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override Boolean TryInvokeMember(InvokeMemberBinder binder, Object?[]? args, out Object? result)
    {
        if (Real == null) throw new ArgumentNullException(nameof(Real));

        result = Real.GetType().InvokeMember(binder.Name, BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, Real, args, CultureInfo.InvariantCulture);

        return true;
    }

    /// <summary>包装</summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static Object Wrap(Object obj)
    {
        //if (obj == null) return null;
        if (obj.GetType().IsPublic) return obj;

        return new DynamicInternal { Real = obj };
    }

    /// <summary>已重载。</summary>
    /// <returns></returns>
    public override String ToString() => Real?.ToString() ?? nameof(DynamicInternal);
}