# How could I reduce repetition with properties/methods?

I'm serializing instances of a lot of classes (in C# 3.0), and I've found myself writing this:

[DataContract]
public class ModelClass
{
public static Guid GetID(ModelClass instance) { ... }

public static T FromID<T>(Guid value) where T : ModelClass { }

[DataMember] public Guid m_id { get; set; }
}

[DataContract]
public class ConcreteModel: ModelClass
{
[DataMember]
public string      m_name;

// Stuff we don't serialize
public Sector      m_sector;
public Theater     m_theater;
public Weather     m_weather;
public TerrainType m_terrainType;

// Link serialized ids to real objects through GetID & FromID
[DataMember] private Guid m_sectorID
{
get { return GetID(m_sector); }
set { m_sector = FromID<Sector>(value); }
}

[DataMember] private Guid m_theaterID
{
get { return GetID(m_theater); }
set { m_theater = FromID<Theater>(value); }
}

[DataMember] private Guid m_weatherID
{
get { return GetID(m_weather); }
set { m_weather = FromID<Weather>(value); }
}

[DataMember] private Guid m_terrainTypeID
{
get { return GetID(m_terrainType); }
set { m_terrainType = FromID<TerrainType>(value); }
}
}


ConcreteModel is just one of many (~100) classes that will have some objects that are going to be saved using IDs, but not the whole objects, so we'll have to write that kind of properties a lot of times.

Is there any way of avoiding this? In C++ I'd be using macros, but not in C#...

My main concern here is not writing those properties all over again like 500 times or more. Any idea on how could I avoid that?

• You're pretty much stuck here, unless you generate the code with a .tt or use Nemerle or F# (which could actually make sense: they certainly do have macros). This is mostly because you're declaring methods for each property. Roslyn may help eventually. Additionally, since this is CodeReview, I have to comment on the horror of your hungarian notation. I'm fine with your alignment though, assuming you're using elastic tabstops and not spaces. May 2 '14 at 16:39
• @Magus AFAIK, F# doesn't have macros. May 3 '14 at 16:22
• Ah, I overestimated the team's cleverness, then. May 5 '14 at 14:12

As @Magus commented, this is as good as it gets.

...almost.

[DataContract]
public class ConcreteModel: ModelClass

[DataMember] public Guid m_id { get; set; }

[DataMember]
public string      m_name;


You're not consistent with how you're placing your DataMemberAttribute attributes; sometimes they're sitting on top of the decorated member, other times they're stuck in front, on the same line. I'd stick to consistently having them on top.

// Stuff we don't serialize
public Sector      m_sector;
public Theater     m_theater;
public Weather     m_weather;
public TerrainType m_terrainType;


Why are these fields public in the first place? You are breaking encapsulation!

[DataMember] private Guid m_sectorID
{
get { return GetID(m_sector); }
set { m_sector = FromID<Sector>(value); }
}


I'm not familiar with serialization using [DataMemberAttribute], but it's rather odd that you expose public fields and declare private serializable properties. Since the fields are exposed anyway, why not just do this?

private Sector m_sector;

[DataMember]
public Guid m_sectorID
{
get { return GetID(m_sector); }
set { m_sector = FromID<Sector>(value); }
}


The naming is, as @Magus commented already, breaking all C# naming conventions. Drop the m_ prefix, and use PascalCase for public members:

private Sector _sector; // or just "sector"

[DataMember]
public Guid SectorId
{
get { return GetId(_sector); }
set { _sector = FromId<Sector>(value); }
}


If ModelClass isn't intended to be instantiated and only serve as a base class, you should make it abstract - also "Class" at the end of a class name is rather useless. How about this?

public abstract class ModelBase


The public static members could made non-static, and be protected so as to only be exposed to the derived types.

• I think I'd also rename ModelClass, but to something slightly different: YourProgramModel, DataModel or something similar. Base can sometimes be a nice suffix to avoid confusion, but it only conveys how it was implemented rather than what it's for, and Model is a very generic word which can mean different things in different contexts. May 2 '14 at 19:03