c#创建动态匿名类型(var)

时间:2017-01-10 21:59:48

标签: c# winforms types

我需要创建一个匿名类型(HAS是一个var)。像这样:

var sizes = new { 
    size = new { Medium = "1", Large = "-3", XL = "10%" } 
};

它必须是动态的,所以下次也可能发生这种情况:

var sizes = new { 
    size = new { 3XL = "5", 4XL = "5%", 5XL = "-10%" } 
};

我如何在C#winforms中执行此操作?

我如何填写var尺寸?它必须按此顺序排列!

1 个答案:

答案 0 :(得分:1)

您可以在运行时创建一个动态类型,其中包含使用System.Reflection.Emit的任何类型的方法和属性,您可以在创建的动态类型中为属性分配默认值。这不是一项简单的练习,它需要一些工作,但是如果你的基本代码完全在你的代码中使用它很容易。

首先,您需要将动态类型附加到当前的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();
    }

动态属性类可以是

/// <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; }
    }
}

动态方法类可以是

/// <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; }
    }
}

启动创建过程。

    /// <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;
    }

如果您可以使用动态类型构建器的完整源代码,请访问https://github.com/nequeo/misc/blob/master/csharp/DynamicTypeBuilder.cs