Can I define properties in partial classes, then mark them with attributes in another partial class?

C#AttributesCode GenerationPartial Classes

C# Problem Overview


Is there a way I can have a generated code file like so:

public partial class A 
{
    public string a { get; set; }
}

and then in another file:

public partial class A 
{
    [Attribute("etc")]
    public string a { get; set; }
}

So that I can have a class generated from the database and then use a non-generated file to mark it up?

C# Solutions


Solution 1 - C#

Here is the solution I have been using for such cases. It is useful when you have auto-generated classes that you want to decorate with attributes. Let's say this is the auto-generated class:

public partial class UserProfile
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

And let's say, I would like to add an attribute to specify that UserId is the key. I would then create a partial class in another file like this:

[Table("UserProfile")]
[MetadataType(typeof(UserProfileMetadata))]
public partial class UserProfile
{
    internal sealed class UserProfileMetadata
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
    }
}

Solution 2 - C#

I've seen something like this done in an article by Scott Guthrie (near the end of it) - didn't try it myself, though.
http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

[MetadataType(typeof(Person_Validation))]
public partial class Person
{
    // Partial class compiled with code produced by VS designer
}

[Bind(Exclude="ID")]
public class Person_Validation
{
    [Required(ErrorMessage = "First Name Required")]
    [StringLength(50, ErrorMessage = "Must be under 50 characters")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Last Name Required")]
    [StringLength(50, ErrorMessage = "Must be under 50 characters")]
    public string LastName { get; set; }

    [Required(ErrorMessage = "Age Required")]
    [Range(0, 120, ErrorMessage = "Age must be between 0 and 120")]
    public int Age { get; set; }

    [Required(ErrorMessage = "Email Required")]
    [Email(ErrorMessage = "Not a valid email")]
    public string Email { get; set; }
}

Solution 3 - C#

This is my answer
different class files or you can combine the metadatas in a same file but keep the namespace the same..so they can see each other obviously.

keep in mind when you update your model like add more columns you have to update the project class too.

--your model class
public partial class A {
    public string a {get; set;}
}

--your project class 
public class Ametadata {
     [Attribute("etc")]
     public string a {get; set;}
}


[MetadataType(typeof(Ametadata))]
public partial class A
{
}

Solution 4 - C#

You need to define a partial class for your A class just like below example

using System.ComponentModel.DataAnnotations;

// your auto-generated partial class
public partial class A 
{
    public string MyProp { get; set; }
}

[MetadataType(typeof(AMetaData))]
public partial class A 
{
    
}

public class AMetaData
{
    [System.ComponentModel.DefaultValue(0)]
    public string MyProp { get; set; }
}

Solution 5 - C#

Not as such; the compiler will complain that the member is defined in multiple parts. However, as the use of custom attributes is reflective in nature, you could define a "metadata" class and use it to contain decorators.

public class A
{
   public string MyString;
}

public class AMeta
{
   [TheAttribute("etc")]
   public object MyString;
}

...

var myA = new A();
var metaType = Type.GetType(myA.GetType().Name + "Meta");
var attributesOfMyString = metaType.GetMember("MyString").GetCustomAttributes();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChris McCallView Question on Stackoverflow
Solution 1 - C#Jean-François BeauchampView Answer on Stackoverflow
Solution 2 - C#Dan DumitruView Answer on Stackoverflow
Solution 3 - C#CyberNinjaView Answer on Stackoverflow
Solution 4 - C#Masoud DarvishianView Answer on Stackoverflow
Solution 5 - C#KeithSView Answer on Stackoverflow