C # Linq Projecting anonymous type on an interface

Is it possible to project using Select onto an anonymous type?

Here is a sample code

public interface ITest { string A{get;} int B{get;} } string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IQueryable<ITest> query = from n in names.AsQueryable() select new {A = n.ToUpper(), B = 2012}; 

The above code calls

It is not possible to implicitly convert the type 'System.Linq.IQueryable' to 'System.Linq.IQueryable'

Note. I can make the above code work if I were to define a Test class that implements ITest, and then a project in this class using:

 select new Test {A = n.ToUpper(), B = 2012}; 

Why? I'm trying to figure out if I can only define an interface and not define a specific implementation of the object, and Linq create me an object.

+6
source share
3 answers

Yes, you can select an anonymous type, but you cannot select an anonymous type, and then use these objects as if they were implementing an interface. The reason is that the anonymous type does not implement the interface, although they have the same properties, both in the type and in the name. There is no way to determine that an anonymous type implements an interface. If you want to use objects through your interface implementations, you need to select a specific type that implements this interface.

Anonymous types are class types that are derived directly from an object and cannot be passed to any type other than an object. The compiler provides a name for each anonymous type, although your application cannot access it. In terms of common language runtime, an anonymous type is no different from any other reference type.

Link: http://msdn.microsoft.com/en-us/library/bb397696.aspx

I can, of course, sympathize with your intentions here. It would be nice if the compiler could understand that the type corresponds to the definition of the interface when the type is anonymous, but this is really only applicable when the interface consists entirely of read-only properties. The moment your interface defines properties using setters or methods, an anonymous type cannot implement it. On the other hand, if you use the anonymous type as you see fit - as a short-term temporary type for a particular use - you can simply reference its properties and you don't need an interface at all.

  var query = from n in names.AsQueryable() select new {A = n.ToUpper(), B = 2012}; foreach (var item in query) { Console.WriteLine( item.A ); } 
+5
source

You cannot do this directly with anonymous objects, but you can achieve something very similar to the Clay framework:

 public interface IPerson { string FirstName { get; set; } string LastName { get; set; } } public static void CastToCLRInterface() { dynamic New = new ClayFactory(); var person = New.Person(); person.FirstName = "Louis"; person.LastName = "Dejardin"; // Concrete interface implementation gets magically created! IPerson lou = person; // You get intellisense and compile time check here Console.WriteLine("{0} {1}", lou.FirstName, lou.LastName); } 
+3
source

You cannot, because anonymous types do not implement interfaces.

To do this, you need to create a class.

One option would be the Duck Typing Project , which essentially generates a shell class at runtime (and therefore, it has a penalty for performance and memory consumption)

(For reference only, anonymous types are real, specific classes generated by the C # compiler. Runtime.net itself does not support them. The C # compiler does not allow you to change how it generates these classes. I tried to find out if Roslyn could help.)

0
source

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


All Articles