2012-11-05 81 views
0

[编辑]与泛型参数创建实例

我再次组织我的问题,

模型参数

public class PaymentModel 
{ 
    ... 
} 

public class CCPaymentModel : PaymentModel 
{ 
    ... 
} 

public class PaypalPaymentModel : PaymentModel 
{ 
    ... 
} 

public class GooglePaymentModel : PaymentModel 
{ 
    ... 
}  

接口类

public interface IPayment<T> where T : PaymentModel 
{ 
    ... 
} 

模型(从IPayment得到继承),

public class SagePayment 
    : IPayment<CreditCardPaymentInfo> 
{ 
    public void MakePayment(CreditCardPaymentInfo creditCardPaymentInfo) { 
     // ... 
    } 

    public void MakeRefund(CreditCardPaymentInfo creditCardPaymentInfo) { 
     // ... 
    } 
} 

public class GooglePayment 
    : IPayment<GooglePaymentModel> 
{ 
    public void MakePayment(GooglePaymentModel paymentInfo) { 
     // ... 
    } 

    public void MakeRefund(GooglePaymentModel paymentInfo) { 
     // ... 
    } 
} 

public class PaypalPayment 
    : IPayment<PayPalPaymentModel> 
{...} 

控制器(创建实例)

IPayment<???> paymentProcess; // //Error 1 Using the generic type 'com.WebUI.Models.IPayment<T>' requires 1 type arguments 

if (Regex.IsMatch(paytype, "^Credit Card")) 
{ 
    paymentProcess = new SagePayment(); // it need CCPaymentModel type parameter 
} 
else if (Regex.IsMatch(paytype, "^PayPal")) 
{ 
    paymentProcess = new PayPalPayment(); // it need PaypalPaymentModel type parameter 
} 
else if (Regex.IsMatch(paytype, "^Google")) 
{ 
    paymentProcess = new GooglePayment(); // it need GooglePaymentModel type parameter 
} 

[EDIT] 

public void Charge(string paytype,orderNo){ 

    IPayment<???> paymentProcess; // //Error 1 Using the generic type 'com.WebUI.Models.IPayment<T>' requires 1 type arguments 
    Object payinfo; 

    if (Regex.IsMatch(paytype, "^Credit Card")) 
    { 
     paymentProcess = new SagePayment(); // <== Error, Can not casting 
     payinfo = getPaymentInfo(paytype, orderNo); // it return CCPaymentModel type object 
    } 
    else if (Regex.IsMatch(paytype, "^PayPal")) 
    { 
     paymentProcess = new PayPalPayment(); 
     payinfo = getPaymentInfo(paytype, orderNo); // it return PaypalPaymentModel type object 
    } 
    else if (Regex.IsMatch(paytype, "^Google")) 
    { 
     paymentProcess = new GooglePayment(); // it return GooglePaymentModel type object 
     payinfo = getPaymentInfo(paytype, orderNo); 
    } 

    paymentProcess.MakePayment(payinfo); 
} 

enter image description here

[EDIT#2]

由此,

public interface IPayment { 
} 

public interface IPayment<T> : IPayment where T : PaymentModel 
{ 
    void MakePayment(string pickno); 
    void makeRefund(T refundInfo); 
} 

我得到一个错误,错误1“COM .WebUI.Models.IPayment'不包含'MakePayment'的定义,也没有扩展方法od'MakePayment'接受类型'Ecom.WebUI.Models.IPayment'的第一个参数可能被发现(您是否缺少使用指令或程序集引用?)

因此,为了避免该错误,我将MakePayment方法上一界面类,

public interface IPayment { 
    void MakePayment(string pickno); 
} 

public interface IPayment<T> : IPayment where T : PaymentModel 
{ 
    void makeRefund(T refundInfo); 
} 

现在,错误走了,但我应该如何在makeRefund情况下怎么办? 我不能移动到上层接口类,因为我需要泛型类型参数。

你能帮我多一点吗?

+2

你想有没有泛型另一个'IPayment'接口,该'IPayment '从...继承。即:'公共接口IPayment :IPayment其中T:PaymentModel'。 –

+1

您将需要通过反射来创建泛型类型:http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx。 –

+0

你想创建一个实例? IPayment是一个界面,所以即使您遵循@ ChrisSinclair的建议,您也无法创建它的实例... – fsimonazzi

回答

6

你会想要另一个IPayment接口没有从哪个IPayment继承的泛型。那就是:

public interface IPayment 
{ 

} 

public interface IPayment<T> : IPayment where T : PaymentModel 
{ 

} 

编辑:如果你真的不希望有一个IPayment基本接口,那么你就必须把他们当作object类型:

object paymentProcess; 

if (Regex.IsMatch(paytype, "^Credit Card")) 
{ 
    paymentProcess = new SagePayment(); 
} 
else if (Regex.IsMatch(paytype, "^PayPal")) 
{ 
    paymentProcess = new PayPalPayment(); 
} 
else if (Regex.IsMatch(paytype, "^Google")) 
{ 
    paymentProcess = new GooglePayment(); 
} 

但可能会花费你后来;无论你将不得不投入使用特定的实现类型。你最好使用基础接口。你甚至可以在一个不错的方式来使用它:

public interface IPayment 
{ 
    PaymentModel Payment { get; } 
} 

所以,你可以参考和使用PaymentModel不知道它实际上是一个专门GooglePaymentModel

编辑:基于您的评论,你可能有这样的:

public interface IPayment 
{ 
    void MakePayment(string pickno); 
} 

public interface IPayment<T> : IPayment where T : PaymentModel 
{ 
    void MakeRefund(T refundInfo); 
} 

你甚至可以有一个非通用MakeRefund版本类型对PaymentModel所以你调用的代码可能不关心,如果它是一个GooglePayment或不。(但可能会导致其他问题,如果他们通过PayPalPayment,所以这是由你)

编辑:基于您最新的代码,你会想是这样的:

public interface IPayment 
{ 

} 

public interface IPayment<T> : IPayment where T : PaymentModel 
{ 
    void MakePayment(T paymentInfo); 
    void MakeRefund(T paymentInfo); 
} 

你的控制器/工厂看起来像:

//not sure on the exact signature since you didn't provide it 
public IPayment CreatePayment(string paytype) 
{ 
    IPayment paymentProcess = null; 

    if (Regex.IsMatch(paytype, "^Credit Card")) 
    { 
     paymentProcess = new SagePayment(); 
    } 
    else if (Regex.IsMatch(paytype, "^PayPal")) 
    { 
     paymentProcess = new PayPalPayment(); 
    } 
    else if (Regex.IsMatch(paytype, "^Google")) 
    { 
     paymentProcess = new GooglePayment(); 
    } 

    return paymentProcess 
} 

你使用的代码会地方必须将它转换为已知的支付类型的使用方法:

IPayment untypedPayment = Factory.CreatePayment("PayPal"); 
IPayment<PayPalPaymentModel> typedPayment = (IPayment<PayPalPaymentModel>)untypedPayment; 
typedPayment.MakePayment(new PayPalPaymentModel()); 

//or alternatively 
IPayment untypedPayment = Factory.CreatePayment("PayPal"); 
PayPalPayment typedPayment = (PayPalPayment)untypedPayment; 
typedPayment.MakeRefund(new PayPalPaymentModel()); 

编辑:根据你最近的编辑,这就是你想要的。针对PaymentModel推动您的基本IPayment调用。然后在具体实施方式可以铸造或在运行时类型检查:

public interface IPayment 
{ 
    void MakePayment(PaymentModel paymentInfo); 
    void MakeRefund(PaymentModel paymentInfo); 
} 

public interface IPayment<T> : IPayment where T : PaymentModel 
{ 

} 

public class GooglePayment 
    : IPayment<GooglePaymentModel> 
{ 
    public void MakePayment(PaymentModel paymentInfo) { 
    GooglePaymentModel googlePayment = (GooglePaymentModel)paymentInfo; 
    // ... 
    } 

    public void MakeRefund(PaymentModel paymentInfo) { 
    GooglePaymentModel googlePayment = (GooglePaymentModel)paymentInfo; 
    // ... 
    } 
} 

那么你Controller

public void Charge(string paytype,orderNo){ 

    IPayment paymentProcess = null; 
    PaymentModel payinfo = null; 

    if (Regex.IsMatch(paytype, "^Credit Card")) 
    { 
     paymentProcess = new SagePayment(); 
     payinfo = getPaymentInfo(paytype, orderNo); 
    } 
    else if (Regex.IsMatch(paytype, "^PayPal")) 
    { 
     paymentProcess = new PayPalPayment(); 
     payinfo = getPaymentInfo(paytype, orderNo); 
    } 
    else if (Regex.IsMatch(paytype, "^Google")) 
    { 
     paymentProcess = new GooglePayment(); 
     payinfo = getPaymentInfo(paytype, orderNo); 
    } 

    paymentProcess.MakePayment(payinfo); 
} 

public PaymentModel getPaymentInfo(string paytype,orderNo) 
{ 
    //return some payment model 
} 
+0

我现在有2种方法在IPayment中,我需要哪些类放置方法? (void MakePayment(string pickno),void makeRefund(T refundInfo)) –

+0

@Expertwannabe取决于它们是否强类型为'PaymentModel'。 'MakePayment'可能可以提升到基类,但是'makeRefund'不会。 –

+0

谢谢你的帮助,但我仍然无法解决问题。你能再次检查我编辑的问题吗?我用更多的代码重写。 –