Implicit collection conversion

This week I ran into a problem regarding implicit conversions in C # in collections. Although this (using implicit ) may not be our final approach, I wanted to at least finish the code to offer the command as an option. I welded the problem to the following example:

I have two classes in my example: one that represents the business object (Foo) and one that represents the client version (View Object) of this business element (FooVO), as defined below ...

 public class Foo { public string Id {get; set;} public string BusinessInfo {get; set;} } public class FooVO { public string Id {get; set;} public static implicit operator FooVO( Foo foo ) { return new FooVO { Id = foo.Id }; } } 

My problem is that I have a list of Foo objects and you want to convert them to a list of FooVO objects using my implicit operator.

 List<Foo> foos = GetListOfBusinessFoos(); // Get business objects to convert 

I tried

 List<FooVO> fooVOs = foos; // ERROR 

and

 List<FooVO> fooVOs = (List<FooVO>) foos; // ERROR 

and even

 List<FooVO> fooVOs = foos.Select( x => x ); // ERROR 

I know I can do this in a loop, but I was hoping for a simple (LINQ?) Way to convert objects into a single snapshot. Any ideas?

Thanks in advance.

Edit Fixed typo in example

+6
source share
4 answers

A question like this is asked almost every day on SO. You cannot do this because it violates type safety:

 List<Giraffe> g = new List<Giraffe>(); List<Animal> a = g; // Should this be legal? a.Add(new Tiger()); // Nope; we just added a tiger to a list of giraffes. 

In C # 4.0, you can implicitly convert from IEnumerable<Giraffe> to IEnumerable<Animal> , because there is no "Add" method to damage things. But you can never do such a β€œcovariant” conversion, as if the conversion of the element types was defined by the user. It should be a reference or a transformation of identity.

You will need to create a second list and copy them one at a time. Or use LINQ helper methods like Select and ToList to do this for you.

The name of the type system concept you want is covariance; the covariant bond is where you reason, "Giraffes are animals, so giraffe sequences are animal sequences." If this topic interests you, you can read about how we added covariance (and contravariance) to C # 4.0 here:

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/default.aspx

Start from the bottom.

+19
source

The reason your examples do not work is because you are trying to assign an IEnumerable<FooVO> List<FooVO> . The following should work.

  List<FooVO> fooVos = foos.Select<Foo,FooVO>(x => x).ToList(); 
+14
source
 List<FooVO> d = new List<FooVO>(foos.Select(x => (FooVO)x)); 

It works for me.

+6
source

Use the ConvertAll method passing in the static implicit operator FooVO( Foo foo ) as an argument

 List<FooVO> fooVOs = foos.ConvertAll<FooVO>(FooVO.FooVO); 
+5
source

Source: https://habr.com/ru/post/890099/


All Articles