Thraka's answer is correct: if you don't want to use generics you need to cast. Just to add to it, in case what you're really trying to do looks something like this. Here's a set of classes that you can expose from your library, which will not be extensible by clients (unless they're running with full trust and can use reflection etc.!!) but which can be used in a type-safe way.
public abstract class SupportedPaymentMethod
{
protected internal SupportedPaymentMethod() { }
}
public sealed class Check : SupportedPaymentMethod
{
public int CheckNumber { get; private set; }
public Check(int checkNumber)
: base()
{
CheckNumber = checkNumber;
}
}
public sealed class CreditCard : SupportedPaymentMethod
{
public CreditCard()
: base()
{ }
}
public abstract class Payment<T>
where T : SupportedPaymentMethod
{
public T Method { get; private set; }
protected internal Payment(T method)
{
Method = method;
}
}
public sealed CheckPayment : Payment<Check>
{
public CheckPayment(Check check)
: base(check)
{ }
}
public sealed CreditCardPayment : Payment<CreditCard>
{
public CreditCardPayment(CreditCard creditCard)
: base(creditCard)
{ }
}
Clients (i.e. code outside of your class library's assembly) will be able to instantiate a CheckPayment
or a CreditCardPayment
, but they will not be able to create a new class deriving from Payment<T>
. So, it will not be possible for clients to create a CheatingPaymentMethod : Payment<Cheating>
, for example. :)
Calls like your intended call to base.Member.A++
will now work:
var checkPayment = new CheckPayment(new Check(123456));
var checkNumber = checkPayment.Method.CheckNumber; // Success! :)