Do not repeat yourself, we teach every fledgling software developer. It makes sense as with growing code redundancy the maintenance cost increase. Simple tools such as functions or loops are a great ways to reduce code redundancy but in our quest to avoid code redundancy we sometimes indulge into complexity. Complex code is also costly to maintain. I will demonstrate, using real-world examples, how one can adopt metaprogramming to minimize code redundancy as well keeping the code simple enough for my mom to understand it.
13. Repeating myself
public class MyViewModel : INotifyPropertyChanged
{
int m_myProperty = 0;
public int MyProperty
{
get { return m_myProperty; }
set
{
m_myProperty = value
OnRaisePropertyChanged ("MyProperty")
}
}
void OnRaisePropertyChanged (string propertyName);
}
15. Repeating myself
public class MyViewModel : INotifyPropertyChanged
{
int m_myProperty = 0;
public int MyProperty
{
get { return m_myProperty; }
set
{
m_myProperty = value
OnRaisePropertyChanged ("MyProperty")
}
}
void OnRaisePropertyChanged (string propertyName);
}
16. Repeating myself
class Customer
{
public long Id ;
public string FirstName;
public string LastName ;
}
public Customer ReadCustomer (IDataReader dr)
{
return new Customer
{
Id = dr.GetInt64 (0),
FirstName = dr.GetString (1),
LastName = dr.GetString (2),
};
}
17. Repeating myself
class Customer
{
public long Id ;
public string FirstName;
public string LastName ;
}
public Customer ReadCustomer (IDataReader dr)
{
return new Customer
{
Id = dr.GetInt64 (0),
FirstName = dr.GetString (1),
LastName = dr.GetString (2),
};
}
19. Repeating myself
class Customer
{
public long Id ;
public string FirstName;
public string LastName ;
}
public Customer ReadCustomer (IDataReader dr)
{
return new Customer
{
Id = dr.GetInt64 (0),
FirstName = dr.GetString (1),
LastName = dr.GetString (2),
};
}
22. Adding complexity
Trading compile-time errors for run-time errors
Hard to get enough test coverage
Hard to understand
No exit strategy
Risky to change
Limited
23.
24. public Customer ReadCustomer (IDataReader dr)
{
return new Customer
{
Id = dr.GetInt64 (0),
FirstName = dr.GetString (1),
LastName = dr.GetString (2),
};
}
25. Adding complexity
Trading compile-time errors for run-time errors
Hard to get enough test coverage
Hard to understand
No exit strategy
Risky to change
Limited
31. class Example
{
public int X0 = 0;
public int X1 = 1;
public int X2 = 2;
public int X3 = 3;
public int X4 = 4;
public int X5 = 5;
public int X6 = 6;
public int X7 = 7;
public int X8 = 8;
public int X9 = 9;
}
T4
32. class Example
{
<# for (var iter = 0; iter < 10; ++iter) { #>
public int X<#=iter#> = <#=iter#>;
<# } #>
}
T4
33. class Example
{
public int X0 = 0;
public int X1 = 1;
public int X2 = 2;
public int X3 = 3;
public int X4 = 4;
public int X5 = 5;
public int X6 = 6;
public int X7 = 7;
public int X8 = 8;
public int X9 = 9;
}
T4
36. Repeating myself
public class MyViewModel : INotifyPropertyChanged
{
int m_myProperty = 0;
public int MyProperty
{
get { return m_myProperty; }
set
{
m_myProperty = value
OnRaisePropertyChanged ("MyProperty")
}
}
void OnRaisePropertyChanged (string propertyName);
}
37. Repeating myself
public class MyViewModel : INotifyPropertyChanged
{
int m_myProperty = 0;
public int MyProperty
{
get { return m_myProperty; }
set
{
m_myProperty = value
OnRaisePropertyChanged ()
}
}
void OnRaisePropertyChanged ([CallerMemberName]string name = null);
}
39. Repeating myself
public class MyViewModel : INotifyPropertyChanged
{
int m_myProperty = 0;
public int MyProperty
{
get { return m_myProperty; }
set
{
m_myProperty = value
OnRaisePropertyChanged ("MyProperty")
}
}
void OnRaisePropertyChanged (string propertyName);
}