简体   繁体   English

C#类型转换

[英]C# Type Conversion

I have two objects. 我有两个对象。 Object A and Object B. 对象A和对象B。

Object A is an instance of a class that was generated from several XSD files. 对象A是从多个XSD文件生成的类的实例。 Used xsd.exe /c and compiled them. 使用xsd.exe / c进行编译。 Now I have my new object. 现在我有了新对象。

I also have a web service, returning something very similar to object A. So right now I have something along the lines of this: 我也有一个Web服务,返回的内容与对象A非常相似。所以现在我有了类似的内容:

WebService.foo myResponseObj = MyService.GetObject(inData);
MyFramework.foo myClientObj = new MyFramework.foo();

What I want to do is this 我想做的是这个

myClientObj = (MyFramework.foo)myResponseObj

However, it's not really liking this. 但是,这并不是真的很喜欢。 Says "Cannot implicitly convert MyFramework.foo[] to WebService.foo[] 说“无法将MyFramework.foo []隐式转换为WebService.foo []

Any ideas on how to resolve this? 有关如何解决此问题的任何想法? The object is quite large and they are basically identical. 对象很大,并且它们基本上是相同的。

Both objects would need to inherit from the same interface in order to successfully perform the cast you have specified. 为了成功执行指定的转换,这两个对象都需要从同一接口继承。 You might look at pulling out the common method(s) you need into an interface that can be implemented in both classes, that way you can just cast to the interface type and then have access to just those methods rather than the entire object. 您可能会考虑将所需的常用方法提取到可以在两个类中都实现的接口中,这样,您可以只转换为接口类型,然后仅访问那些方法而不是整个对象。

Enjoy! 请享用!

How about extracting the interface (right click on one class, select Refactor->Extract Interface), and apply this interface to both classes? 如何提取接口(右键单击一个类,选择Refactor-> Extract Interface),然后将此接口应用于两个类呢?

So it will look something like: 因此,它将类似于:

namespace WebService
{
   public class foo : IExtractedInterface
}

and

namespace MyFramework
{
   public class foo : IExtractedInterface
}

You should then be able to do: 然后,您应该可以执行以下操作:

IExtractedInterface myClientObj = (IExtractedInterface)myResponseObj;

You need to make a method that converts one class into the other by manually copying all of the properties. 您需要提供一种通过手动复制所有属性将一个类转换为另一个类的方法。

You can then call that method in Array.ConvertAll . 然后,您可以在Array.ConvertAll调用该方法。

Them being "basically identical" is insufficient. 他们“基本相同”是不够的。 You can only cast between two objects if they are type-compatible, meaning that they share a common descendant and the actual types are valid for casting. 如果它们在类型上兼容,则只能在两个对象之间进行转换,这意味着它们共享一个公共后代,并且实际类型对于转换有效。

For example, the following works if Circle is a descendant of Shape : 例如,如果CircleShape的后代,则以下工作:

Shape x = new Circle();
Circle y = (Circle)x;

However, the following will not work event if ClassA and ClassB have the exact same fields but are not actually descended from each other: 但是,以下将无法正常工作,如果事件ClassAClassB有相同的字段,但实际上并没有从对方的后裔:

ClassA a = new ClassA();
ClassB b = (ClassA)a;

It may be worthwhile to make them both implement a common interface, then you could cast to that interface and use them the way you want. 使它们都实现一个通用接口可能是值得的,然后您可以转换为该接口并以所需方式使用它们。

This has basically been answered already . 基本上已经回答了 Note, however, that in addition to what's been answered here, there is a small glimmer of hope provided by .NET 4's new "Type Equivalence" feature: 但是请注意,除了此处已回答的内容外,.NET 4的新“类型等效”功能还带来了一丝希望:

Note however that C# 4 will support a limited form of structural typing on interfaces. 但是请注意,C#4将在接口上支持有限形式的结构化类型。 See http://blogs.msdn.com/samng/archive/2010/01/24/the-pain-of-deploying-primary-interop-assemblies.aspx for details. 有关详细信息,请参见http://blogs.msdn.com/samng/archive/2010/01/24/the-pain-of-deploying-primary-interop-assemblies.aspx

This is pretty advanced .NET-foo, though. 不过,这是相当高级的.NET-foo。

If you're using the standard wsdl.exe tool to create your proxy and supporting classes, then I believe it generates the code as partial classes. 如果您使用标准的wsdl.exe工具创建代理和支持类,那么我相信它将生成代码作为部分类。 If that is your situation, then you could insert your own implicit conversion operator to one of the types. 如果是这种情况,则可以将自己的隐式转换运算符插入其中一种类型。 For instance, let's say you have your MyService.foo class defined in the file "MyService\\foo.cs" as below: 例如,假设您在文件“ MyService \\ foo.cs”中定义了MyService.foo类,如下所示:

namespace MyService
{
    public partial class foo
    {
        public string PropertyA { get; set; }
        public string PropertyB { get; set; }
        public string PropertyC { get; set; }
        // ...
    }
}

And you have your MyFramework.foo class defined in the file "MyFramework\\foo.cs" as below: 并且您在文件“ MyFramework \\ foo.cs”中定义了MyFramework.foo类,如下所示:

namespace MyFramework
{
    public class foo
    {
        public string PropertyA { get; set; }
        public string PropertyB { get; set; }
        public string PropertyC { get; set; }
        // ...
    }
}

Then you can create a separate file, let's say "MyService\\foo.conversion.cs" as below: 然后,您可以创建一个单独的文件,如下所示:“ MyService \\ foo.conversion.cs”:

namespace MyService
{
    partial class foo
    {
        public static implicit operator MyFramework.foo(foo input)
        {
            return new MyFramework.foo
            {
                PropertyA = input.PropertyA,
                PropertyB = input.PropertyB,
                PropertyC = input.PropertyC,
                // ...
            };
        }
    }
}

And that would allow you to write most of your code using a MyService.foo object as if it were a MyFramework.foo object. 这样一来,您就可以使用MyService.foo对象编写大多数代码,就好像它是MyFramework.foo对象一样。 The following code compiles with the above setup: 以下代码使用上述设置进行编译:

        MyService.foo x = new MyService.foo();

        MyFramework.foo y = x;

如果它是一个数组(您在引号中提出了建议),则必须遍历响应集合并将成员对象添加到客户端集合中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM