2010-05-11 54 views
1

我已經設置了一個類來驗證信用卡號碼。信用卡類型和號碼在單獨的課程表格中選擇。我試圖找出如何獲得信用卡類型和數量都在其他類(frmPayment)中選擇我的信用卡類算法:如何使用單獨的類來驗證C#中的信用卡號碼

public enum CardType 
{ 
    MasterCard, Visa, AmericanExpress 
} 

public sealed class CardValidator 
{ 
    public static string SelectedCardType { get; private set; } 
    public static string CardNumber { get; private set; } 

    private CardValidator(string selectedCardType, string cardNumber) 
    { 
     SelectedCardType = selectedCardType; 
     CardNumber = cardNumber; 
    } 

    public static bool Validate(CardType cardType, string cardNumber) 
{ 
    byte[] number = new byte[16]; 


    int length = 0; 
    for (int i = 0; i < cardNumber.Length; i++) 
    { 
     if (char.IsDigit(cardNumber, i)) 
     { 
      if (length == 16) return false; 
      number[length++] = byte.Parse(cardNumber[i]); //not working. find different way to parse 
     } 
    } 

    switch(cardType) 
    { 
    case CardType.MasterCard: 
     if(length != 16) 
      return false; 
     if(number[0] != 5 || number[1] == 0 || number[1] > 5) 
      return false; 
     break; 

    case CardType.Visa: 
     if(length != 16 & length != 13) 
      return false; 
     if(number[0] != 4) 
      return false; 
     break; 

    case CardType.AmericanExpress: 
     if(length != 15) 
      return false; 
     if(number[0] != 3 || (number[1] != 4 & number[1] != 7)) 
      return false; 
     break; 

    } 

    // Use Luhn Algorithm to validate 
    int sum = 0; 
    for(int i = length - 1; i >= 0; i--) 
    { 
    if(i % 2 == length % 2) 
    { 
     int n = number[i] * 2; 
     sum += (n/10) + (n % 10); 
    } 
    else 
     sum += number[i]; 
    } 
    return (sum % 10 == 0); 

}}

回答

1

frmPayments (或類似的)事件處理程序,只需調用CardValidator.Validate方法。

但是,CardValidator構造函數具有參數,即使它是私人的,並從來沒有調用?你爲什麼要給課堂添加屬性?

編輯:錯過了一些你的示例代碼。

+0

+1在第二段。你可能不希望ctor採取參數,然後可能在方法中忽略它們。如果是我,我會讓唯一的ctor變成私人的,放棄這兩個屬性,並保持整個類的靜態。然後當我想驗證調用CardValidator.Validate(type,number); – 2010-05-11 21:17:24

+0

尚未完成。我剛剛開始嘗試從我的frmPayment類中調用它,但無法完全找到一種方法來做到這一點。這就是爲什麼我的構造函數還沒有完成。我只是在 – EvanRyan 2010-05-11 21:18:57

2

對於初學者來說,我會使用正則表達式做簡單的驗證(所有的數字,具體的長度。)

但你的問題的點,我不知道我理解的問題是什麼。從你在這裏發佈的內容看來,你可能應該放棄構造函數,並將整個事物設置爲靜態類。

public enum CardType 
{ 
    MasterCard, 
    Visa, 
    AmericanExpress, 
} 

public static class CardValidator 
{ 
    public static bool Validate(CardType cardType, string cardNumber) 
    { 
     string strippedCardNumber = Regex.Replace(cardNumber, @"\D", String.Empty); 


     ICardValidator validator = SelectCardValidator(cardType); 

     return validator.Validate(strippedCardNumber); 
    } 

    private static ICardValidator SelectCardValidator(CardType cardType) 
    { 
     switch (cardType) 
     { 
      case CardType.MasterCard: 
       return new MasterCardValidator(); 
      case CardType.Visa: 
       return new VisaValidator(); 
      case CardType.AmericanExpress: 
       return new AmericanExpressValidator(); 
      default: 
       return new UnknownCardTypeValidator(); 
     } 
    } 

    private interface ICardValidator 
    { 
     bool Validate(string cardNumber); 
    } 

    private class UnknownCardTypeValidator : ICardValidator 
    { 
     #region ICardValidator Members 

     public bool Validate(string cardNumber) 
     { 
      return false; 
     } 

     #endregion 
    } 

    private abstract class LuhnAlgorithmValidator : ICardValidator 
    { 

     #region ICardValidator Members 

     public virtual bool Validate(string cardNumber) 
     { 
      // Implement Luhn Algorithm here 

      return false; 
     } 

     #endregion 
    } 

    private class MasterCardValidator : LuhnAlgorithmValidator 
    { 
     public override bool Validate(string cardNumber) 
     { 
      bool isValid = false; // replace with MasterCard validation 
      return isValid && base.Validate(cardNumber); 
     } 
    } 

    private class VisaValidator : LuhnAlgorithmValidator 
    { 
     public override bool Validate(string cardNumber) 
     { 
      bool isValid = false; // replace with Visa validation 
      return isValid && base.Validate(cardNumber); 
     } 
    } 

    private class AmericanExpressValidator : LuhnAlgorithmValidator 
    { 
     public override bool Validate(string cardNumber) 
     { 
      bool isValid = false; // replace with AmEx validation 
      return isValid && base.Validate(cardNumber); 
     } 
    } 
} 
+0

之前沒有做過這樣的事情,這似乎是對的。我仍然是一個初學者程序員,所以我仍然經常犯相當基本的錯誤 – EvanRyan 2010-05-11 21:42:40

5

您錯過了更好的面向對象和更簡潔的代碼的好機會。

class CreditCard 
{ 
    public CreditCard(string number, string expiration, string cvv2) {...} 

    public virtual bool IsValid() 
    { 
     /* put common validation logic here */ 
    } 

    /* factory for actual cards */ 
    public static CreditCard GetCardByType (CardType card, string number, string expiration, string cvv2) 
    { 
     switch (card) 
     { 
      case CardType.Visa: 
        return new VisaCreditCard(...); 

      ... 
     } 
    } 
} 

class VisaCreditCard : CreditCard 
{ 
    public VisaCreditCard (string number, string expiration, string cvv2) 
     : base (number, expiration, cvv2) 
    {...} 

    public override bool IsValid() 
    { 
     /* check Visa rules... */ 
     bool isValid = ... 

     return isValid & base.IsValid(); 
    } 
} 
+0

這是一個非常乾淨的解決方案。 – Tyler 2010-05-11 21:56:24