当前位置:  开发笔记 > 编程语言 > 正文

在C#中使用相同布局强制不同命名空间中的类型

如何解决《在C#中使用相同布局强制不同命名空间中的类型》经验,为你挑选了2个好方法。

我已经开始为FedEx的webservice API编写一个接口.他们有3种不同的API,我很感兴趣; 费率,发货和跟踪.我正在使用SvcUtil.exe生成服务代理.

FedEx在自己的WSDL文件中指定了不同的服务端点.每个服务端点都有自己的xml命名空间(例如http://fedex.com/ws/rate/v5和http://fedex.com/ws/ship/v5)

服务端点确实使用了相当多的相同类型,例如Address,Measurements,Weight,AuthenticationDetail,ClientDetail等......

这就是问题所在,我可以同时向SvcUtil.exe提供所有WSDL文件,通常它会将任何相同的类型合并为一个共享类型,但由于FedEx的每个服务都在它们自己的命名空间中,他们在该命名空间下的每个WSDL文件中重新声明这些类型,而不是每个命名空间的Address,Address1和Address2.

为了解决这个问题,我现在要做的是分别通过svcutil运行每个WSDL,并将它们分别放在自己的.NET命名空间中(例如FedEx.Rate,FedEx.Ship,FedEx.Track).这个问题是现在我在每个命名空间中都有一个不同的地址类型(Fedex.Rate.Address,FedEx.Ship.Address).

这使得很难概括像GetAuthenticationDetail()工厂方法之类的服务之间使用的代码,因此我不必在每个使用不同服务的地方重复该代码.

在C#中是否有任何方法可以将FedEx.Rate.Address强制转换为FedEx.Ship.Address?



1> zildjohn01..:

如果类型相同,并且您可以控制源类,则可以在类中定义转换运算符,并且任何带有Rate.Address意志的函数也会自动获取Ship.Address.例如:

namespace Rate {
    class Address {
        string Street;
        string City;
        // ...

        public static implicit operator Ship.Address(Rate.Address addr) {
            Ship.Address ret;
            ret.Street = addr.Street;
            ret.City = addr.City;
            // ...

            return ret;
        }
    }
}

我的C#有点生疏,但我希望你明白这个想法.



2> joshperry..:

所以这是我如何使用反射实现隐式转换运算符.SvcUtil创建了部分类,因此我为每个转换方向添加了一个隐式转换运算符,因此在客户端代码中您只需键入即可Type1 = Type2.

在这个片段中,WebAuthenticationCredentials是WebAuthenticationDetails的一个属性,因此如果类型不同(内置函数),则迭代源对象的属性时,它会检查类型的名称(没有命名空间),并使用这些属性递归调用复制函数.

internal class ReflectionCopy
{
    public static ToType Copy(object from) where ToType : new()
    {
        return (ToType)Copy(typeof(ToType), from);
    }

    public static object Copy(Type totype, object from)
    {
        object to = Activator.CreateInstance(totype);

        PropertyInfo[] tpis = totype.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        PropertyInfo[] fpis = from.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        // Go through each property on the "to" object
        Array.ForEach(tpis, tpi =>
        {
            // Find a matching property by name on the "from" object
            PropertyInfo fpi = Array.Find(fpis, pi => pi.Name == tpi.Name);
            if (fpi != null)
            {
                // Do the source and destination have identical types (built-ins)?
                if (fpi.PropertyType == tpi.PropertyType)
                {
                    // Transfer the value
                    tpi.SetValue(to, fpi.GetValue(from, null), null);
                }
                else
                {
                    // If type names are the same (ignoring namespace) copy them recursively
                    if (fpi.PropertyType.Name == tpi.PropertyType.Name)
                        tpi.SetValue(to, Copy(fpi.PropertyType, tpi.GetValue(from, null)), null);
                }
            }
        });

        return to;
    }
}

namespace Rate
{
    partial class WebAuthenticationDetail
    {
        public static implicit operator Ship.WebAuthenticationDetail(WebAuthenticationDetail from)
        {
            return ReflectionCopy.Copy(from);
        }
    }

    partial class WebAuthenticationCredential
    {
        public static implicit operator Ship.WebAuthenticationCredential(WebAuthenticationCredential from)
        {
            return ReflectionCopy.Copy(from);
        }
    }
}

namespace Ship
{
    partial class WebAuthenticationDetail
    {
        public static implicit operator Rate.WebAuthenticationDetail(WebAuthenticationDetail from)
        {
            return ReflectionCopy.Copy(from);
        }
    }

    partial class WebAuthenticationCredential
    {
        public static implicit operator Rate.WebAuthenticationCredential(WebAuthenticationCredential from)
        {
            return ReflectionCopy.Copy(from);
        }
    }
}

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有