copy an attribute of a property from one instance to another instance (of a different type ) at runtime

我怕爱的太早我们不能终老 提交于 2019-12-24 02:23:31

问题


let's say I have 2 classes like this:

public class Foo
{
[Required]
public string Name {get;set;}
}

public class Bar 
{
// put here [Required] at run-time
public string Name {get;set;}
}

var foo = new Foo();
var bar = new Bar();
//copy the required from foo to bar

is it possible to copy the attributes from foo to bar at run-time ?


回答1:


The notion of "copying" attributes is out. However, you can do something meaningful in the code that checks if the attribute is applied. You could use another attribute that tells the code that it should use another type to verify for the [Required] attribute. For example:

[AttributeUsage(AttributeTargets.Class)]
public class AttributeProviderAttribute : Attribute {
    public AttributeProviderAttribute(Type t) { Type = t; }
    public Type Type { get; set; }
}

Which you'd use like this:

public class Foo {
    [Required]
    public string Name { get; set; }
}

[AttributeProvider(typeof(Foo))]
public class Bar {
    public string Name { get; set; }
}

The code that checks for the attribute could look like this:

    static bool IsRequiredProperty(Type t, string name) {
        PropertyInfo pi = t.GetProperty(name);
        if (pi == null) throw new ArgumentException();
        // First check if present on property as-is
        if (pi.GetCustomAttributes(typeof(RequiredAttribute), false).Length > 0) return true;
        // Then check if it is "inherited" from another type
        var prov = t.GetCustomAttributes(typeof(AttributeProviderAttribute), false);
        if (prov.Length > 0) {
            t = (prov[0] as AttributeProviderAttribute).Type;
            return IsRequiredProperty(t, name);
        }
        return false;
    }

Note how this code allows the attribute provider to be chained.




回答2:


Attributes aren't attached to instances -- they're attached to type definitions.

While you can create new types at runtime using reflection, you cannot change existing type definitions.




回答3:


Whether this is possible depends on which libraries need to see the attribute. If the code that needs to see this uses reflection, then you're scuppered. You can't do it.

However; if the code that needs this uses the component model, it is possible - but it is a lot of work. You could implement a TypeDescriptionProvider that creates a per-instance ICustomTypeDescriptor, and defines custom-chained PropertyDescriptor instances. You would then supplement (or replace) the attribute(s) per-property, passing them into the base-constructor (or override the attributes property). The upshot is that the following will then include your attribute:

var attribs = TypeDescriptor.GetProperties(obj)["Name"].Attributes;

Things like winforms data-binding use this API, but it won't care much about your custom attribute. You'll excuse me not writing a full example, but that is a lot of work; none of those interfaces / base-types is trivial to implement. Ultimately, I doubt it is worth it.




回答4:


Attributes are a part of the meta-data of the (compiled and loaded) assembly, so I don't think you could modify them at runtime easily.

The only option I can think of is generating code with the attribute using CodeDOM and re-compiling it (and re-loading the assembly), or doing the same thing using System.Reflection.Emit (which would be possible, but very complicated).

Why do you want to do this? Perhaps there is an easier way to solve your problem...




回答5:


If you need attributes to perform data binding or other task related to UI, you may try to alter default behavior of TypeDescriptor.

Looks here http://msdn.microsoft.com/en-us/library/ms171819.aspx

You may add your custom type descriptor for type, and it allows you provide custom attributes to some components that uses TypeDescriptor.GetXXX members instead of operating directly with type metadata.




回答6:


Am I missing the point here? Wy not use an implicit operator?

Bus bus;
BigVehicle big = bus;

public static implicit operator Bigvehicle(Bus bus)
{

}



回答7:


Please have a look at AutoMapper. AutoMapper is a mapper framework that can convert DTO objects to domain model objects.

Introduction info: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx

Binary release site: http://automapper.codeplex.com

Source code release site: http://code.google.com/p/automapperhome/



来源:https://stackoverflow.com/questions/3037805/copy-an-attribute-of-a-property-from-one-instance-to-another-instance-of-a-diff

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!