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&lt;T&gt;(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 &amp; FromID
    [DataMember] private Guid m_sectorID
    {
        get { return GetID(m_sector); }
        set { m_sector = FromID&lt;Sector&gt;(value); }
    }

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

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

    [DataMember] private Guid m_terrainTypeID
    {
        get { return GetID(m_terrainType); }
        set { m_terrainType = FromID&lt;TerrainType&gt;(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?
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&lt;Sector&gt;(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&lt;Sector&gt;(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&lt;Sector&gt;(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.