views:

38

answers:

3

The fake code is:

  public class ParentClass
      { decimal quantity, 
        decimal price
      }

  IQueryable<ParentClass> parents;

  //SonClass is created at run time 
  //SonClass has some extra property, such as amount=quantity*price, which is defined by a string at run time

  IQueryable<SonClass> sons=parents.Select(p=>new SonClass(p){ attachedProperty1=..., attachedProperty2=...})

If I have the source code of ParentClass, I know how to create the sonClass at run time. Actually SonClass should have a suitable constructor for the Linq select statement. I tried the following fake code:

    public SonClass(ParentClass parent)
{
... 
}

When we don't have the source code of ParentClass, how to write a generic code ?

Or, maybe you have a new way to get the same result. The desired results is to create a subclass of ParentClass dynamically with extra read only properties defined by Linq Select statement.

Thank you in advance.

Ying

A: 

you need not construct any sub class, an anonymous class is generated for you at runtime

var sons=parents.Select(p=>new { attachedProperty1=p..., attachedProperty2=p...})
foreach (var son in sons){
     Console.WriteLine(son.PropertyName);
}
Rony
+1  A: 

I don't believe this is (currently) possible. From the C# Programmers Guide at MSDN, regarding anonymous types:

Anonymous types are reference types that derive directly from object. The compiler gives them a name although your application cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other reference type, except that it cannot be cast to any type except for object.

Nathan Ernst
A: 

It sounds like you want to create a dynamic type that extends an existing type and injects custom properties. I'm pretty sure that's impossible in a single LINQ statement (you'd need either C#4.0 dynamics or some reflection madness).

However, you can create anonymous classes with any properties you like:

var sons = parents.Select(p =>new { parentProperty1=p.Prop1, attachedProperty1=..., tachedProperty2=...});

Or:

var sons = parents.Select(p =>new { parent=p, attachedProperty1=..., tachedProperty2=...});

Alternatively, why don't you have an "additional properties" (type object or Dictionary) property on your ParentClass so you could do this:

var sons = parents.ForEach(p => p.AdditionalProps = new { attachedProperty1=..., tachedProperty2=...});

You could write an extension method that used reflection to grab all the public properties of a given object, merge them with a given anonymous object (your "attachedProperty1 etc. object") and return a new anonymous object with all merged properties. However, this would be a poor solution - a better solution would probably be to return a Dictionary<string, object> instead of an anonymous type because even if you did create a merged anonymous type you wouldn't be able to access its properties in a type-safe manner.

Graphain