Creating an Anonymous Type Dynamically

Creating an anonymous type dynamically?

Only ExpandoObject can have dynamic properties.

Edit:
Here is an example of Expand Object usage (from its MSDN description):

dynamic sampleObject = new ExpandoObject();
sampleObject.TestProperty = "Dynamic Property"; // Setting dynamic property.
Console.WriteLine(sampleObject.TestProperty );
Console.WriteLine(sampleObject.TestProperty .GetType());
// This code example produces the following output:
// Dynamic Property
// System.String

dynamic test = new ExpandoObject();
((IDictionary<string, object>)test).Add("DynamicProperty", 5);
Console.WriteLine(test.DynamicProperty);

How to define anonymous object property dynamically?

Anonymous types are immutable, you can only create and set properties when creating the instance. This means you need to create the exact object you need. So you could do something like this instead:

if (fields.Contains("picture_url"))
{
return Ok(new
{
id = userProfile.UserId,
email = userProfile.Email,
name = userProfile.Name,
picture_url = "path"
});
}

return Ok(new
{
id = userProfile.UserId,
email = userProfile.Email,
name = userProfile.Name
});

Another option is to used a Dictionary<string, object>. For example:

var userInfo = new Dictionary<string, object>
{
{"id", userProfile.UserId},
{"email", userProfile.Email},
{"name", userProfile.Name}
};

if (fields.Contains("picture_url"))
{
// error in this line
userInfo.Add("picture_url", "path");
}

return Ok(userInfo);

This object will serialise to the same JSON structure:

{"id":1,"email":"email@somewhere.com","name":"Bob","picture_url":"path"}

How to dynamic new Anonymous Class?

Anonymous types are just regular types that are implicitly declared. They have little to do with dynamic.

Now, if you were to use an ExpandoObject and reference it through a dynamic variable, you could add or remove fields on the fly.

edit

Sure you can: just cast it to IDictionary<string, object>. Then you can use the indexer.

You use the same casting technique to iterate over the fields:

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;

foreach (var property in (IDictionary<string, object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33

The above code and more can be found by clicking on that link.

How to make an anonymous types property name dynamic?

No, even anonymous types must have compile-time field names. It seems like to want a collection of different types, each with different field names. Maybe you could use a Dictionary instead?

  var result = linqDoc.Descendants()
.GroupBy(elem => elem.Name)
.ToDictionary(
g => g.Key.ToString(),
g => g.Attributes("Id").Select(attr => attr.Value).ToList()
);

Note that Dictionaries can be serialized to JSON easily:

{ 
"key1": "type1":
{
"prop1a":"value1a",
"prop1b":"value1b"
},
"key2": "type2":
{
"prop2a":"value2a",
"prop2b":"value2b"
}
}

Anonymous Types - How to dynamically create?

You could use a lambda expression to accomplish this:

var data2 = myList.Select(x => new { Name = x.Stat, Value = x.Total }).ToArray();

return Json(data2);

Dynamically create an object from an anonymous object

Yes, it is possible. To use the type as a type argument, you need to use the MakeGenericType method:

// Of course you'll use CreateType here but this is what compiles for me :)
var anonymous = new { Value = "blah", Number = 1 };
Type anonType = anonymous.GetType();

// Get generic list type
Type listType = typeof(List<>);
Type[] typeParams = new Type[] { anonType };
Type anonListType = listType.MakeGenericType(typeParams);

// Create the list
IList anonList = (IList)Activator.CreateInstance(anonListType);

// create an instance of the anonymous type and add it
var t = Activator.CreateInstance(anonType, "meh", 2); // arguments depending on the constructor, the default anonymous type constructor just takes all properties in their declaration order
anonList.Add(t);

c# creating a dynamically anonymous types (var)

You can create a dynamic type at runtime which contains methods and properties of any type using System.Reflection.Emit, you can assign default values into your properties within the dynamic type created. This is not a trivial exercise and it needs some work, but when you have the base code complete using it in your code is easy.

First you need to attach your dynamic type to your current AppDomain.

private AssemblyName _assemblyName;
private AssemblyBuilder _asssemblyBuilder;

private ModuleBuilder _moduleBuilder;
private Dictionary<SignatureBuilder, Type> _classes;

private ReaderWriterLock _rwLock;
private TypeBuilder _typeBuilder;
private string _typeName;

/// <summary>
/// Default constructor.
/// </summary>
/// <param name="moduleName">The name of the assembly module.</param>
public DynamicTypeBuilder(string moduleName)
{
// Make sure the page reference exists.
if (moduleName == null) throw new ArgumentNullException("moduleName");

// Create the nw assembly
_assemblyName = new AssemblyName(moduleName);
_asssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run);

// Create only one module, therefor the
// modile name is the assembly name.
_moduleBuilder = _asssemblyBuilder.DefineDynamicModule(_assemblyName.Name);

// Get the class unique signature.
_classes = new Dictionary<SignatureBuilder, Type>();
_rwLock = new ReaderWriterLock();
}

The dynamic property class can be

/// <summary>
/// Dynamic property builder, with value assigned.
/// </summary>
public class DynamicPropertyValue
{
object value;
string name;
Type type;

/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">The name of the property.</param>
/// <param name="type">The type of the property</param>
/// <param name="value">The value of the property.</param>
public DynamicPropertyValue(string name, Type type, object value)
{
if (name == null) throw new ArgumentNullException("name");
if (type == null) throw new ArgumentNullException("type");
if (value == null) throw new ArgumentNullException("value");
this.name = name;
this.type = type;
this.value = value;
}

/// <summary>
/// Gets, the property name.
/// </summary>
public string Name
{
get { return name; }
}

/// <summary>
/// Gets, the property type.
/// </summary>
public Type Type
{
get { return type; }
}

/// <summary>
/// Gets, the property value.
/// </summary>
public object Value
{
get { return value; }
}
}

The dynamic method class can be

/// <summary>
/// Dynamic method builder.
/// </summary>
public class DynamicMethod
{
string name;
IEnumerable<Type> parameters;
Type returnType;
Action<TypeBuilder> buildAction = null;

/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">The name of the method.</param>
/// <param name="parameters">The collection parameter types.</param>
/// <param name="returnType">The return type.</param>
public DynamicMethod(string name, IEnumerable<Type> parameters, Type returnType)
{
if (name == null) throw new ArgumentNullException("name");

this.name = name;
this.parameters = parameters;
this.returnType = returnType;
}

/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">The name of the method.</param>
/// <param name="parameters">The collection parameter types.</param>
/// <param name="returnType">The return type.</param>
/// <param name="buildAction">The build action.</param>
public DynamicMethod(string name, IEnumerable<Type> parameters, Type returnType, Action<TypeBuilder> buildAction)
{
if (name == null) throw new ArgumentNullException("name");

this.name = name;
this.parameters = parameters;
this.returnType = returnType;
this.buildAction = buildAction;
}

/// <summary>
/// Gets, the method name.
/// </summary>
public string Name
{
get { return name; }
}

/// <summary>
/// Gets, the collection of parameters
/// </summary>
public IEnumerable<Type> Parameters
{
get { return parameters; }
}

/// <summary>
/// Gets, the return type.
/// </summary>
public Type ReturnType
{
get { return returnType; }
}

/// <summary>
/// Gets, build action.
/// </summary>
public Action<TypeBuilder> BuildAction
{
get { return buildAction; }
}
}

Start the create process.

    /// <summary>
/// Create a new instance of the dynamic type.
/// </summary>
/// <param name="typeName">The name of the type.</param>
/// <param name="properties">The collection of properties to create in the type.</param>
/// <param name="methods">The collection of methods to create in the type.</param>
/// <returns>The new instance of the type.</returns>
public object Create(string typeName, IEnumerable<DynamicPropertyValue> properties, IEnumerable<DynamicMethod> methods)
{
// Make sure the page reference exists.
if (typeName == null) throw new ArgumentNullException("typeName");
if (properties == null) throw new ArgumentNullException("properties");
if (methods == null) throw new ArgumentNullException("methods");

_typeName = typeName;

// Create the dynamic type collection
List<DynamicProperty> prop = new List<DynamicProperty>();
foreach (DynamicPropertyValue item in properties)
prop.Add(new DynamicProperty(item.Name, item.Type));

// Return the create type.
object instance = CreateEx(typeName, prop.ToArray(), methods);
PropertyInfo[] infos = instance.GetType().GetProperties();

// Assign each type value
foreach (PropertyInfo info in infos)
info.SetValue(instance, properties.First(u => u.Name == info.Name).Value, null);

// Return the instance with values assigned.
return instance;
}

If this is something you can use the complete source code for the dynamic type builder can be found at https://github.com/nequeo/misc/blob/master/csharp/DynamicTypeBuilder.cs



Related Topics



Leave a reply



Submit