如何将命名空间传递给方法

本文关键字:方法 命名空间 | 更新日期: 2023-09-27 18:29:37

namespace MyOldService
{    
    public MyNewService.AddressList ToPrivateAddressList()
    {
        MyNewService.AddressList privAddrList = new MyNewService.AddressList();
        privAddrList.creator = (MyNewService.AddressListCreator)this.creator;
        privAddrList.listId = this.listId;
        privAddrList.listIdSpecified = this.listIdSpecified;
        privAddrList.listName = this.listName;
        privAddrList.listType = (MyNewService.AddressingMode)this.listType;
        privAddrList.lastModified = this.lastModified;
        privAddrList.lastModifiedSpecified = this.lastModifiedFieldSpecified;
        if (this.siteList != null && this.listType == MyOldService.AddressingMode.XDAddressingModeSiteIDList)
        {
            privAddrList.siteList = new long[this.siteList.Length];
            Array.Copy(this.siteList, privAddrList.siteList, this.siteList.Length);
        }
        ...

最初编写用于将 SOAP 命名空间 MyOldService 中定义的列表复制到新命名空间 MyNewService 中具有相同布局的类。 问题是,对于 soap 类,如果我将 MyOldService 命名空间导入到第三个命名空间(例如 MyOtherAppService(中,那么我的 AddressList 类将成为该第三个命名空间的成员,并按此引用。

因此,与其复制代码,我想用类似于泛型的东西来装饰它(或以某种方式调整它((我知道这不起作用,因为我正在更改命名空间,而不仅仅是一个固定类型 [每个命名空间都需要多种类型,从代码片段中可以看出](允许它将地址列表转换为所需的命名空间中的相应类。 可能?

编辑:为了回应下面的一些评论,我将尝试定义一个更好的例子来说明我正在尝试做的事情。

通过 Web 引用从 WSDL 导入的三个类(不,这些类不会编译,只是举例说明(。 类地址列表都具有相同的布局。

namespace A
{    
    enum Mode {};
    enum Creator {};
    class ATypeClass {}
    public partial class AddressList
    {
        int id;
        enum Mode mode;
        enum Creator creator
        long[] siteList;
        ATypeClass[] cspList;
    }
}
namespace B
{    
    enum Mode {};
    enum Creator {};
    class BTypeClass {}
    public partial class AddressList
    {
        int id;
        enum Mode mode;
        enum Creator creator
        long[] siteList;
        BTypeClass[] cspList;
    }
}
namespace C
{    
    enum Mode {};
    enum Creator {};
    class CTypeClass {}
    public partial class AddressList
    {
        int id;
        string name;
        enum Mode mode;
        enum Creator creator
        long[] siteList;
        CTypeClass[] cspList;
    }
}

我将使用新方法扩展命名空间 A 中的分部类:

namespace A
{
    public partial class AddressList
    {
        public T.AddressList ToPrivateAddressList<T>()
        {
            T.AddressList privAddrList = new T.AddressList();
            privAddrList.creator = (T.Creator)this.creator;
            privAddrList.id = this.id;
            privAddrList.name = this.name;
            privAddrList.mode = (T.Mode)this.mode;
            if (this.siteList != null && this.listType == Mode.XDAddressingModeSiteIDList)
            {
                privAddrList.siteList = new long[this.siteList.Length];
                Array.Copy(this.siteList, privAddrList.siteList, this.siteList.Length);
            }
            ...
        }
    }
}

请注意,除了不同命名空间的每个部分的类之外,问题的一部分是也来自不同命名空间的枚举。

最后,我

设想这样称呼它(虽然我知道我实际上不能这样做,但我正在寻找一个大致同样优雅的解决方案(:

B.AddressList al1 = A.AddressList.ToPrivateAddressList<B>();
C.AddressList al1 = A.AddressList.ToPrivateAddressList<C>();

如何将命名空间传递给方法

我认为您正在寻找的是泛型类型定义中的接口和where关键字。

从您的代码中,我看到您有这个:

  • 将类型 A 转换为类型 B 的方法
  • 它通过分配具有相同名称的属性来实现此目的
  • 然后返回新的类型 B
  • 这些类型可以驻留在不同的命名空间中(但当前具有相同的名称(
  • 类是partial

与其依赖相同的名称(你可以使用反射来实现你想要的效果(,不如让每个类实现一个包含公共属性的接口。这样,您可以保留编译时类型安全:

public interface ICommonAddress 
{
    int id { get; set; }
    Mode mode { get; set; }
    Creator creator { get; set; }
    long[] siteList { get; set; }
    ICommonAddress CreateAddress();
}

现在可以像这样重构您的类(当然,您必须将字段更改为属性,但我假设您已经将它们作为属性:

// if your original partial class is auto-generated, it is ok to place 
// this definition in another file, it'll still work as long as 
// namespace, classname and compile-unit (must be in same project) are the same
public partial class AddressList : ICommonAddress
{
    int id { get; set; }
    Mode mode { get; set; }
    Creator creator { get; set; }
    long[] siteList { get; set; }
    ATypeClass[] cspList;
    ICommonAddress CreateAddress()
    {
        return new AddressList();   // NOTE: you can even have your ctor private!
    }
}

如果对拥有的每个地址列表类型执行此操作,则可以按如下所示更改泛型方法,它将自动工作,包括显示常见可用属性的智能感知。此外,将其实现为扩展方法,以便它适用于所有地址列表类型(在您的情况下,这比使用 partial 更好(:

public T ToPrivateAddressList<T>(this ICommonAddress _this)
    where T: ICommonAddress
{
    T privAddrList = _this.CreateAddress();
    // this now works normally, without casting
    privAddrList.creator = _this.creator;
    privAddrList.id = _this.id;
    privAddrList.name = _this.name;
    privAddrList.mode = _this.mode;
}

现在,如果导入对此扩展方法的引用,则可以对具有的任何类型调用ToPrivateAddressList()

A.AddressList a_address = A.AddressList.CreateAddress();   // or new A.AddressList()
B.AddressList al1 = a_address.ToPrivateAddressList<B.AddressList>();
C.AddressList al1 = a_address.AddressList.ToPrivateAddressList<C.AddressList>();

如果我正确地解决了你的问题,你有

namespace A
{
    public class MyClass {... }
}

namepsace B
{  
   public class MyClass {...}
}

您的问题是:我如何定义一些"通用"的东西,该"通用"功能有时在同一函数中处理A.MyClass和其他情况B.MyClass.

如果您将命名空间视为类型定义的一部分,我认为故事变得清晰起来。就像你有 2 种不同的类型,并希望有一个适用于这两种类型的泛型。该泛型类知道何时选择A.MyClass方法,以及何时选择B.MyClass方法。

如果这不是您想要的,请澄清。

你是在问你怎么能做到这一点吗:

namespace Old
{
  public New.Address Foo()
  {
    New.Address result;
    //...
    return result;
  }
}

不必在每次出现地址时说"新"?但是如果你不这样做,代码会使用 Old.Address

你能从这个项目的构建/链接中删除 Old.Address 吗(使用此代码(?