我对C#泛型有疑问。我希望在我的抽象类中存储泛型类型变量,而不在类外声明该类型。
以下是代码示例。请注意,我不希望将 Param 类暴露在 Calc 类之外。
提前致谢。 - Dutta。
abstract class Base { }
abstract class Calc<T> where T : Base
{
protected Param Member; /* how can this be a made a generic declaration
* WITHOUT declaring this class like,
* class Calc<T, P>
* where T : Base
* where P : Param */
protected Calc(Param p)
{
this.Member = p;
}
protected abstract class Param { }
}
class MyBase : Base { }
class MyCalc : Calc<MyBase>
{
public MyCalc() : base(new MyParam()) { }
public void doSomething()
{
base.Member.A++; // fails on compilation
}
private class MyParam : Calc<MyBase>.Param
{
public int A;
public MyParam() { this.A = 0; }
}
}
答案 0 :(得分:1)
你只需要将它转换为新类型,因为无论如何,变量Member被声明为Param并且它将始终作为Param访问:
((MyParam)base.Member).A++;
其次,您可以通过更改以下内容来修复MyParam类:
MyParam : Calc<MyBase>.Param
对此:
MyParam : Param
因为Param已经通过泛型和继承Calc<MyBase>
了。
答案 1 :(得分:0)
Thraka的回答是正确的:如果你不想使用泛型,你需要施放。只是添加它,以防你真正想要做的事情看起来像这样。这是一组可以从库中公开的类,它们不会被客户端扩展(除非它们以完全信任的方式运行并且可以使用反射等。!!)但是可以以类型安全的方式使用。
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)
{ }
}
客户端(即类库的程序集之外的代码)将能够实例化CheckPayment
或CreditCardPayment
,但是他们将无法创建源自{{1}的新类}。因此,例如,客户端无法创建Payment<T>
。 :)
拨打CheatingPaymentMethod : Payment<Cheating>
之类的电话现在可以正常工作:
base.Member.A++