If you absolutely had to be using two lists of the base class:
public abstract class Unit()
{
public abstract Unit Add(Unit other);
public void MatchType(Unit other)
{
if(this.GetType() != other.GetType())
throw new ArgumentException("Units not of same type");
}
}
...then implement the following in each derived class:
public override void Add(Unit other)
{
MatchType(other);
//actual implementation
}
then extend this functionality in your derived classes with the actual Add implementation.
Honestly, I do not see the point of what you're trying to do. It wouldn't work unless both lists contained only Measures or only Weights, and you're just hiding that fact from the consumer by putting type-checking into Unit. That's just asking for trouble.
I would define the code you have these two lists in as follows:
public List<T> AddLists<T>(List<T> firstList, List<T> secondList) where T:Unit
{
//your code to add elements
}
... then use a generic Unit.Add() method as follows:
public static void Add<T>(this T item, T other) where T:Unit
{
//perform something that works like item += other
}
You'd have to use lists strongly typed to Weight or Measure. You can try to convert a List's generic parameter using Linq:
listOfMeasures = listOfUnits.OfType<Weight>().ToList();
Of course this will cause Weights to be filtered out of the list, but this can work to your advantage:
listOfWeights = listOfUnits.OfType<Weight>().ToList();
listOfMeasures = listOfUnits.OfType<Measure>().ToList();
var addedListOfMeasures = AddLists(listOfMeasures, otherListOfMeasures);
var addedListOfWeights = AddLists(listofWeights, otherListOfWeights);
The above code, used with the generic AddLists and Unit.Add() methods I laid out, will be type-safe and thus won't throw any runtime exceptions. Doesn't make it good; any new Unit you create will require adding more code to this to handle each new type.