使用泛型参数创建实例

Exp*_* be 0 c# generics interface

[编辑]

我再次组织我的问题,

参数模型

public class PaymentModel
{   
    ... 
}

public class CCPaymentModel : PaymentModel
{
    ...
}

public class PaypalPaymentModel : PaymentModel
{
    ...
}

public class GooglePaymentModel : PaymentModel
{
    ...
}    
Run Code Online (Sandbox Code Playgroud)

接口类

public interface IPayment<T> where T : PaymentModel
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

模型(从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>
{...}
Run Code Online (Sandbox Code Playgroud)

控制器(创建实例)

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);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

[编辑#2]

有了这个,

public interface IPayment {
}

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

我收到一个错误,错误1'com.WebUI.Models.IPayment'不包含'MakePayment'的定义,并且没有扩展方法'MakePayment'接受类型'Ecom.WebUI.Models.IPayment'的第一个参数可以找到(您是否缺少using指令或程序集引用?)

因此,为了避免该错误,我将MakePayment方法移动到上层接口类,

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

public interface IPayment<T> : IPayment where T : PaymentModel
{
    void makeRefund(T refundInfo);
}
Run Code Online (Sandbox Code Playgroud)

现在,错误消失了,但我应该怎么做makeRefund案例?我无法移动到上层接口类,因为我需要泛型类型参数.

你能帮我一点吗?

Chr*_*air 6

您可能希望拥有另一个IPayment接口,而不使用IPayment继承的泛型.那是:

public interface IPayment
{

}

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

}
Run Code Online (Sandbox Code Playgroud)

编辑:如果你真的不想拥有一个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();
}
Run Code Online (Sandbox Code Playgroud)

但这可能会让你以后付出代价; 无论你是否需要使用特定的实现类型进行转换.你最好使用基本界面.您甚至可以以一种很好的方式使用它:

public interface IPayment
{
    PaymentModel Payment { get; }
}
Run Code Online (Sandbox Code Playgroud)

所以你可以参考和使用它PaymentModel而不知道它实际上是一个GooglePaymentModel具体的.

编辑:根据您的评论,你可能有类似的东西:

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

public interface IPayment<T> : IPayment where T : PaymentModel
{
    void MakeRefund(T refundInfo);
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用非泛型MakeRefund版本进行打字,PaymentModel这样您的调用代码可能不关心它是GooglePayment不是.(但如果他们通过了PayPalPayment,可能会导致其他问题,所以这取决于你)

编辑:根据您的最新代码,你会想要这样的东西:

public interface IPayment
{

}

public interface IPayment<T> : IPayment where T : PaymentModel
{
    void MakePayment(T paymentInfo);
    void MakeRefund(T paymentInfo);
}
Run Code Online (Sandbox Code Playgroud)

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

//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
}
Run Code Online (Sandbox Code Playgroud)

您使用的代码将某处必须将它转换为已知的支付类型的使用方法:

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());
Run Code Online (Sandbox Code Playgroud)

编辑:根据您的最新编辑,这是你想要的.针对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;
    // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你的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
}
Run Code Online (Sandbox Code Playgroud)