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导入的三个类(不,这些不会编译,只是用于说明的示例)。类AddressList都具有相同的布局。
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>();
答案 0 :(得分:0)
如果我对您的问题不满意
namespace A
{
public class MyClass {... }
}
和
namepsace B
{
public class MyClass {...}
}
您的问题是:我如何定义在同一函数中有时会处理A.MyClass
和其他情况B.MyClass
的“通用”内容。
如果您考虑名称空间类似于类型定义的一部分,我认为这个故事就变得清晰了。
就像你有两种不同的类型,并希望有一个适用于它们的通用。该通用类知道何时选择A.MyClass
方法,以及何时选择B.MyClass
方法。
如果不是您所要求的,请澄清。
答案 1 :(得分:0)
您是否在询问如何执行此操作:
namespace Old
{
public New.Address Foo()
{
New.Address result;
//...
return result;
}
}
无需说'新'。&#39;每次出现地址?但是,如果您不这样做,代码会使用Old.Address
?
您可以从此项目的构建/链接中删除Old.Address(使用此代码)吗?
答案 2 :(得分:0)
我认为你要找的是接口和泛型类型定义中的where
关键字。
从你的代码我看到你有这个:
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!
}
}
如果对每个AddressList类型执行此操作,则可以按如下方式更改通用方法,它将自动运行,包括显示常用属性的IntelliSense。此外,将其实现为扩展方法,以便它适用于您的所有AddressList类型(在您的情况下比使用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>();