Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#泛型:我可以约束到一组不';你不能实现一个接口吗?_C#_.net_Generics - Fatal编程技术网

C#泛型:我可以约束到一组不';你不能实现一个接口吗?

C#泛型:我可以约束到一组不';你不能实现一个接口吗?,c#,.net,generics,C#,.net,Generics,我有3个基本相同的类,但没有实现接口,因为它们都来自不同的web服务 e、 g 服务1.Object1 服务2.1 服务3.1 它们都具有相同的属性,我正在编写一些代码,以便使用实现我自己的接口IObject1的中间对象将它们相互映射 我已经使用泛型完成了这项工作 public static T[] CreateObject1<T>(IObject1[] properties) where T : class, new() { //Check the type is a

我有3个基本相同的类,但没有实现接口,因为它们都来自不同的web服务

e、 g

  • 服务1.Object1
  • 服务2.1
  • 服务3.1
它们都具有相同的属性,我正在编写一些代码,以便使用实现我自己的接口IObject1的中间对象将它们相互映射

我已经使用泛型完成了这项工作

public static T[] CreateObject1<T>(IObject1[] properties)
  where T : class, new()
{
   //Check the type is allowed
   CheckObject1Types("CreateObject1<T>(IObject1[])", typeof(T));
   return CreateObjectArray<T>(properties);
}

private static void CheckObject1Types(string method, Type type)
{
  if (type == typeof(Service1.Object1)
  || type == typeof(Service2.Object1)
  || type == typeof(Service3.Object1)
  || type == typeof(Service1.Object1[])
  || type == typeof(Service2.Object1[])
  || type == typeof(Service3.Object1[]))
  {
     return;
  }

  throw new ArgumentException("Incorrect type passed to ServiceObjectFactory::" + method + ". Type:" + type.ToString());
}
publicstatict[]CreateObject1(ioobject1[]properties)
其中T:class,new()
{
//检查类型是否允许
CheckObject1Types(“CreateObject1(IOObject1[])”,typeof(T));
返回CreateObjectArray(属性);
}
私有静态void checkobject1类型(字符串方法、类型)
{
if(type==typeof(Service1.Object1)
||type==typeof(Service2.Object1)
||type==typeof(Service3.Object1)
||type==typeof(Service1.Object1[]
||type==typeof(Service2.Object1[]
||type==typeof(Service3.Object1[]))
{
返回;
}
抛出新ArgumentException(“传递给ServiceObjectFactory的类型不正确:“+method+”。类型:“+type.ToString());
}
我的客户端代码如下所示:

//properties is an array of my intermediary objects
Object1[] props = ServiceObjectFactory.CreateObject1<Object1>(properties);
//属性是我的中间对象的数组
Object1[]props=ServiceObjectFactory.CreateObject1(属性);
我想做的是摆脱CheckObject1Types方法,改为使用约束,以便在类型无效时出现生成错误,因为目前我可以用任何类型调用此方法,并且ArgumentException由CheckObject1Types方法引发

所以我想做一些类似的事情:

public static T[] CreateObject1<T>(IObject1[] properties)
  where T : class, new(), Service1.Object1|Service2.Object1|Service3.Object1
{
   return CreateObjectArray<T>(properties);
}
publicstatict[]CreateObject1(ioobject1[]properties)
其中T:class,new(),Service1.Object1 | Service2.Object1 | Service3.Object1
{
返回CreateObjectArray(属性);
}
有什么想法吗


编辑:我不想更改每个web服务的Reference.cs文件,因为只需要团队成员更新web引用和BAM!错误的代码。

在C#中不可能像您希望的那样以“或”的方式约束类列表。(事实上,我甚至不确定它是否直接在IL合法。)

您唯一的选择是继续使用checktypes样式函数。如果您拥有不同Web服务的代码,您还可以实现“sentinel”接口并将其用作约束。我知道根据框架设计指南,sentinel接口不是推荐的做法,但它们有时也有其用途(这就是其中之一)

正如Jon所指出的,您可以使用prtial类来实现公共接口。如果您的References.cs实现了一个类:

namespace TestServices
{
   internal partial class Service1SoapClient : System.ServiceModel.ClientBase<T>, K
   {
   }
}

如果您从web服务中提取这些对象,您完全可以控制所使用的类定义。它们并不是凭空冒出来的(即使最初是由代码生成器或VisualStudio创建的)。每个类的某个地方都有一个类文件,必须使用应用程序编译,您应该能够将通用接口添加到这些类定义中。

假设生成的类是部分类,您可以创建一个接口,然后添加另一个部分源文件,以使生成的类实现该接口。然后,您可以像正常情况一样通过接口进行约束。不需要更改实际生成的代码:)

我将编写一个转换器类,将三个对象中的任何一个转换为支持所需接口的新对象。此外,我将使用反射,这样您就不必手动键入所有赋值(除非它是一个小对象,并且预计不会有太多更改)


使用反射还可以保证您希望确保对象实现新接口对象实现的任何属性,否则,当您期望的属性没有实现时,您可能会让它抛出一个错误。

我刚刚注意到,通过将它从&&更改为| |和!=在任何人指出这一点之前。很公平,我希望你被证明是错的!关于这是为什么有任何扩展?我没有自己的代码-是的,我可以浏览Reference.cs并手动将每个类分配给一个公共接口,但是如果团队成员更新了web引用-BAM!没有更多的接口。请参阅Jon Skeet关于使用分部类从公共接口派生所有内容的可能性的回答。请参阅本文,了解为什么没有实现“打开类型”功能,这可能有许多相同的原因。这不是源代码管理的目的吗?是的,我只是不喜欢这样做。代码气味?即使使用源代码管理,每次对reference.cs进行更改都会重新提交。仍然需要有人去手动恢复到“接口”副本…这就是我想要得到的。关于部分类技巧的好观点。我刚刚查看了我在VS2008(.NET 3.5)中使用服务引用创建的一个新项目,它确实将客户端创建为一个分部类。。。我来试试。好主意。我没有意识到您实际上可以访问服务代理的源代码。这将是解决你问题的理想办法。来自meJon的Upvote,你有没有在你的网站上发布过这样的例子?我很想看看。
namespace TestServices
{
   internal interface ICommon
   {
   }

   internal partial class Service1SoapClient : ICommonInterface
   {
   }
}