简体   繁体   English

使用通用参数创建实例

[英]Create instance with generic parameter

[EDIT] [编辑]

I organize my question again, 我再次整理我的问题,

Models for parameter 参数模型

public class PaymentModel
{   
    ... 
}

public class CCPaymentModel : PaymentModel
{
    ...
}

public class PaypalPaymentModel : PaymentModel
{
    ...
}

public class GooglePaymentModel : PaymentModel
{
    ...
}    

Interface class 接口类

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

Models (get inheritance from IPayment), 模型(从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>
{...}

Controller (Create instance) 控制器(创建实例)

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);
}

在此处输入图片说明

[EDIT #2] [编辑#2]

With this, 有了这个,

public interface IPayment {
}

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

I got an error, Error 1 'com.WebUI.Models.IPayment' does not contain a definition for 'MakePayment' and no extension method 'MakePayment' accepting a first argument of type 'Ecom.WebUI.Models.IPayment' could be found (are you missing a using directive or an assembly reference?) 我收到一个错误,错误1'com.WebUI.Models.IPayment'不包含'MakePayment'的定义,并且找不到扩展方法'MakePayment'接受类型为'Ecom.WebUI.Models.IPayment'的第一个参数(您是否缺少using指令或程序集引用?)

So, to avoid that error, I move MakePayment method to upper interface class, 因此,为避免该错误,我将MakePayment方法移至上层接口类,

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

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

Now, the error is gone, BUT how should I do in makeRefund case? 现在,错误消失了,但是在makeRefund情况下我该怎么办? I can not move to upper interface class because I need generic type parameter. 我无法使用上层接口类,因为我需要通用类型参数。

Could you help me a little more please? 你能帮我一点吗?

You would want to have another IPayment interface without the generics from which IPayment inherits from. 您可能希望有另一个IPayment接口,而没有IPayment继承自的泛型。 That is: 那是:

public interface IPayment
{

}

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

}

EDIT: If you really don't want to have an IPayment base interface, then you'd have to treat them as type object : 编辑:如果您真的不想拥有IPayment基本接口,则必须将它们视为type 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();
}

But that might cost you later; 但这可能会在以后花费您; regardless you're going to have to cast to work with the specific implementation types. 无论您将要强制转换为使用特定的实现类型。 You're really best using a base interface. 使用基础界面确实是最好的选择。 You may even use it in a nice way: 您甚至可以很好地使用它:

public interface IPayment
{
    PaymentModel Payment { get; }
}

So you can reference and use the PaymentModel without knowing that it's actually a GooglePaymentModel specifically. 因此,您可以引用和使用PaymentModel而不用知道它实际上是GooglePaymentModel

EDIT: Based on your comment, you might have something like: 编辑:根据您的评论,您可能会有类似的内容:

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

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

You could even have a non-generic MakeRefund version typed against PaymentModel so your calling code might not care if it's a GooglePayment or not. 你甚至可以有一个非通用MakeRefund类型对版本PaymentModel所以你调用的代码可能不关心,如果它是一个GooglePayment与否。 (but that could cause other issues if they pass a PayPalPayment , so that's up to you) (但是,如果他们通过PayPalPayment ,则可能会导致其他问题,这取决于您)

EDIT: Based on your latest code, you'll want something like this: 编辑:根据您的最新代码,您将需要以下内容:

public interface IPayment
{

}

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

Your controller/factory would look like: 您的控制器/工厂看起来像:

//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
}

Your usage code would somewhere have to cast it to the known payment type to use: 您使用的代码将某处必须将它转换为已知的支付类型的使用方法:

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());

EDIT: Based on your latest edits, this is what you want. 编辑:根据您的最新编辑,这就是您想要的。 Drive your base IPayment calls against a PaymentModel. 针对PaymentModel推动您的基本IPayment调用。 Then in the specific implementations you can cast or type-check at runtime: 然后,在特定的实现中,您可以在运行时进行强制转换或类型检查:

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;
    // ...
    }
}

Then your Controller : 然后您的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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM