Powershell, использующий библиотеку c #, не распознает перегруженные методы с разными типами возвращаемых данных. - PullRequest
0 голосов
/ 11 января 2019

Мой код имеет две функции с разными типами возвращаемых значений и разной параметризацией. Каждый берет единственную строку и возвращает bool. Другой принимает массив строк и возвращает словарь. Когда мы запускаем библиотеку из консольного приложения c # .Net, она распознает перегрузку и выбирает правильный тип возвращаемого значения. Когда мы импортируем модуль, содержащий dll, в Powershell и передаем функции строку, мы получаем логический тип возврата, как и ожидалось. Однако, когда мы передаем массив строк, мы все равно получаем логический тип возврата, как будто он не обнаруживает перегруженный метод. Тем не менее, мы не получаем никаких ошибок при передаче функции неправильного типа параметра, мы просто возвращаем «false».

Мы попытались привести тип передаваемого массива, а также тип возвращаемого значения к словарю. Мы также проверяли обычную перегрузку с теми же типами возврата, и она работала нормально.

// Код C #

public static class StringTests
{
    /// <summary>
    /// Test a string for valid email format
    /// </summary>
    /// <param name="email">email string to test</param>
    /// <returns>true if valid email format</returns>

    public static bool ValidateEmailFormat(string email)
    {
        Dictionary<string, string> exp = StoredRegEx.StoredExpressions;

        // Fail if two periods in a row
        if (Regex.IsMatch(email, exp["DoublePeriod"]))
        {
            return false;
        }

        // Fail if leading character is a period
        if (Regex.IsMatch(email, exp["LeadPeriod"]))
        {
            return false;
        }

        // Splitting email string around '@' delimeter.  We can test the results to check for multiple @'s, or @'s in the wrong location
        string[] splitEmail = email.Split('@');

        // Fail if anything other than exactly one '@' symbol in string.  If there is one '@' symbol located in email string that is not either the first 
        // or last character, then we should always get a string array with a length of two when we split.
        if (splitEmail.Length != 2)
        {
            return false;
        }

        // Fail if local string does not match local format
        if (!Regex.IsMatch(splitEmail[0], exp["LocalFormat"]))
        {
            return false;
        }

        // Fail if domain string is longer than 255 chars
        if (splitEmail[1].Length > 255)
        {
            return false;
        }

        // Fail if domain string begins or ends with a hyphen               TODO: Research if its exclusively hyphen because like dollar signs and percetages probably don't work
        if (splitEmail[1].StartsWith("-") || splitEmail[1].EndsWith("-"))
        {
            return false;
        }

        // Turn the domain string into subdomains around a '.' delimeter to check if any of the subdomains 
        string[] subDomains = splitEmail[1].Split('.');

        foreach (string subDomain in subDomains)
        {
            if (subDomain.Length > 63)
            {
                return false;
            }
        }

        // Fail if domain does not match domain format
        if(!Regex.IsMatch(splitEmail[1], exp["DomainFormat"]))
        {
            return false;
        }

        return true;
    }

    /// <summary>                                                                                                                                   // currently the overloaded dictionary return type is not working with powershell
    /// Overload takes an array of email strings and return dictionary with bool validation
    /// </summary>
    /// <param name="emails"></param>
    /// <returns></returns>
    public static Dictionary<string, bool> ValidateEmailFormat(string[] emails)
    {
        Dictionary<string, bool> validatedEmails = new Dictionary<string, bool>();

        foreach(string email in emails)
        {
            bool emailValid = ValidateEmailFormat(email);

            validatedEmails.Add(email, emailValid);
        }

        return validatedEmails;
    }

// Код Powershell

Import-Module .\DotNetForPowershell.dll
$ArrayOfEmails = ("test@test.com", "@anotheremail.com", "em.ail@test.com" 
[DotNetForPowershell.Utils.StingTests]::ValidateEmailFormat($ArrayOfEmails)

Ожидается: передача массива строк возвращает объект словаря

Actual: передача массива строк возвращает «false».

1 Ответ

0 голосов
/ 11 января 2019

Вы пытались привести переменную как строковый массив?

Import-Module .\DotNetForPowershell.dll
$ArrayOfEmails = ("test@test.com", "@anotheremail.com", "em.ail@test.com")
[DotNetForPowershell.Utils.StingTests]::ValidateEmailFormat([System.String[]]$ArrayOfEmails)

PSObject по некоторым причинам может интерпретироваться как строка.

...