红着眼 2023-12-14 18:42 采纳率: 27.8%
浏览 13
已结题

C# 委托类型对象转换的问题。委托对象转换。

关于委托方法中,我怎么转换对象的问题。
我在调试代码的时候,都能看到func.Target 里面的SG.SGService.WCFRefObj;对象,为什么转换出来就是空的呢?
SG.SGService.WCFRefObj wcfRefObj = func.Target as SG.SGService.WCFRefObj;
这个转换出来是null的。
调试代码的图片如下。

img

img

代码如下

using System;
using System.Linq;
using SG.com.ll.Config;
using System.ServiceModel;
using System.Collections.Generic;
using SG.SGService;
using System.Reflection;

namespace SG.com.ll.Method
{
    /// <summary>
    /// Wcf服务调用辅助类
    /// </summary
    public static class WCFHelper<TChannel> where TChannel : ICommunicationObject, new()
    {
        private static Dictionary<string, TChannel> _ChannelDic = new Dictionary<string, TChannel>();
        private static object _Lockhelper = new object();

        private static TResult TryFunc<TResult>(Func<TChannel, TResult> func, TChannel channel, ref bool isSuccess, ref string msg)
        {
            string tChannelName = typeof(TChannel).FullName;
            try
            {
                isSuccess = true;
                return func(channel);
            }
            catch (CommunicationException ex)
            {
                channel.Abort();
                lock (_Lockhelper)
                    _ChannelDic.Remove(tChannelName);
                isSuccess = false;
                msg = ex.Message;
                return default(TResult);
            }
            catch (TimeoutException ex)
            {
                channel.Abort();
                lock (_Lockhelper)
                    _ChannelDic.Remove(tChannelName);
                isSuccess = false;
                msg = ex.Message;
                return default(TResult);
            }
            catch (Exception ex)
            {
                channel.Abort();
                lock (_Lockhelper)
                    _ChannelDic.Remove(tChannelName);
                isSuccess = false;
                msg = ex.Message;
                return default(TResult);
            }
        }

        private static TChannel GetChannel()
        {
            TChannel instance;
            string tChannelName = typeof(TChannel).FullName;
            if (!_ChannelDic.ContainsKey(tChannelName))
            {
                lock (_Lockhelper)
                {
                    instance = Activator.CreateInstance<TChannel>();
                    _ChannelDic.Add(tChannelName, instance);
                }
            }
            else
            {
                instance = _ChannelDic[tChannelName];
            }
            if (instance.State != CommunicationState.Opened && instance.State != CommunicationState.Opening)
                instance.Open();
            return instance;
        }

        //<summary>
        //直接调用,无返回值
        //</summary>
        public static void Invoke(Action<TChannel> action)
        {
            TChannel instance = GetChannel();
            bool isSuccess = true;
            string refMsg = string.Empty;
            TryFunc(client =>
                    {
                        action(client);
                        return (object)null;
                    }, instance, ref isSuccess, ref refMsg);
        }

        /// <summary>
        /// 有返回值的调用
        /// </summary>
        public static TResult Invoke<TResult>(Func<TChannel, TResult> func)
        {
            TChannel instance = GetChannel();
            TResult returnValue = default(TResult);
            bool isSuccess = true;
            string refMsg = string.Empty;
            returnValue = TryFunc(func, instance, ref isSuccess, ref refMsg);
            //获取对象转换
            SG.SGService.WCFRefObj wcfRefObj = func.Target as SG.SGService.WCFRefObj;
            if (wcfRefObj.IsSuccess)
            {
                string str = "WCF内部方法返回正确";
            }
            else
            {
                string str = String.Format("WCF内部方法返回失败,失败代码{0}失败的详情{1}", wcfRefObj.ErrorCode, wcfRefObj.Message);
            }
            return returnValue;
        }
    }
}

WCF方法调用

WCFRefObj wcfRefObj = new WCFRefObj();
NEWWCFHelper<SGServiceClient>.Invoke((client, WCFRefObj) => client.ChenckDevice(1001, ref wcfRefObj));
  • 写回答

18条回答 默认 最新

  • 专家-郭老师 Java领域新星创作者 2023-12-14 18:44
    关注
    获得0.45元问题酬金

    稍等,正在为您修改。
    你在调试的时候能看到 func.Target 是 SG.SGService.WCFRefObj 类型,但在转换的时候得到的结果是 null,这可能是由于 func 未正确绑定到目标对象。在C#的委托中, Target 属性返回绑定到的目标对象,委托可以指向静态方法(这种情况下 Target是null),也可以指向实例方法(此时 Target 是调用方法的对象)。
    在你的代码中,你的 func 是 Func<TChannel, TResult> 类型,在这个委托的定义中,此委托方法并没有实例对象,即 func.Target 会是 null。
    另外,在你的 Invoke 方法中,你试图从 func.Target 进行类型转换:

    SG.SGService.WCFRefObj wcfRefObj = func.Target as SG.SGService.WCFRefObj;
    
    

    这个尝试会失败,因为 func.Target 是 null,因此 wcfRefObj 结果会是 null。
    如果你希望转换 SG.SGService.WCFRefObj 类型的对象,你需要从正确的地方获取这个对象实例,正如你在WCF方法调用中所做的那样:

    WCFRefObj wcfRefObj = new WCFRefObj();
    NEWWCFHelper<SGServiceClient>.Invoke((client, WCFRefObj) => client.ChenckDevice(1001, ref wcfRefObj));
    
    

    在这里, wcfRefObj 是由你手动创建和管理的 SG.SGService.WCFRefObj 对象,你应该直接使用这个对象,而不是从 func.Target 进行转换。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月22日
  • 创建了问题 12月14日

悬赏问题

  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,
  • ¥15 angular项目错误