簡體   English   中英

無法理解C#泛型

[英]Can't understand C# Generics

我能夠理解C#Generics,但只有當我在一本易於理解的例子中閱讀它時才能理解它。 但在現實生活中,我會看到復雜的C#Generics代碼,如下所示。 有人可以向我解釋這段代碼的一般方面嗎? 我看到了類型參數,但不明白為什么T沒有在方法體中使用。 T如何在體內使用?

public void ValidateExceptionFromResponse<T>( BaseClaimResponseDataContract<T> response )
    {
        if (response.CommunicationResponseCodes != null && response.CommunicationResponseCodes.Any())
        {
            var validateResult = new ValidationResults();
            foreach (var communicationResponseCodeDataContract in response.CommunicationResponseCodes)
            {
                validateResult.AddResult( new ValidationResult(communicationResponseCodeDataContract.Description.Current, null, null, null, null));
            }
            throw FaultManager.GenerateFault(validateResult);
        }
        if( response.MessageError != null )
        {
            throw FaultManager.GenerateFault(eErrorCodes.Claims, response.MessageError.Current);
        }
    }

以下是BaseClaimResponseDataContract的代碼段:

[KnownType(typeof(SummaryClaimsReportResponseDataContract))]
[KnownType(typeof(ClaimResponseDataContract))]
[KnownType(typeof(CommunicationResponseDataContract))]
[DataContract]
public class BaseClaimResponseDataContract<T>
{
    [DataMember]
    public bool IsRxClaim { get; set; }

    [DataMember]
    public ThirdPartyDataContract ThirdParty { get; set; }

    [DataMember]
    public ExternalSystemMessages RequestMessage { get; set; }

    [DataMember]
    public bool RequestAccepted { get; set; }

    [DataMember]
    public string ResponseStatus { get; set; }

    [DataMember]
    [StringLength(10)]
    public string ResponseCodes { get; set; }

    [DataMember]
    public string[] ResponseCodesArray
    {
        get
        {
            var lstMessageCodes = new List<string>();

            if (!string.IsNullOrEmpty(ResponseCodes))
            {
                for (int i = 0; i < ResponseCodes.Length / 2; i++)
                {
                    var code = ResponseCodes.Substring(i*2, 2);
                    if (!string.IsNullOrWhiteSpace(code))
                        lstMessageCodes.Add(code);
                }
            }

            return lstMessageCodes.ToArray();
        }
    }

    [DataMember]
    public IEnumerable<CommunicationResponseCodeDataContract> CommunicationResponseCodes;

    [DataMember]
    public StringDataContract MessageError { get; set; }

    public void CopyFrom(BaseClaimResponseDataContract<T> claimResponse)
    {
        IsRxClaim = claimResponse.IsRxClaim;
        ThirdParty = claimResponse.ThirdParty;
        RequestMessage = claimResponse.RequestMessage;
        RequestAccepted = claimResponse.RequestAccepted;
        ResponseStatus = claimResponse.ResponseStatus;
        ResponseCodes = claimResponse.ResponseCodes;
        CommunicationResponseCodes = claimResponse.CommunicationResponseCodes;
        MessageError = claimResponse.MessageError;
    }
}

在這種情況下,泛型參數的唯一目的似乎是強制該方法的參數必須是BaseClaimResponseDataContract<T> 我懷疑你的解決方案中有多種類型從中繼承,例如:

public class SomeSample : BaseClaimResponseDataContract<AnotherClass> 
{
}

該方法只能通過實現此基類型的實例調用,因此它就像一種帶有接口的標記類的形式。

該方法是通用的,因為它采用通用參數。 為了指定參數的類型,使用泛型,這意味着該方法本身采用泛型參數。

在這種情況下,這不是方法,而是泛型:它是論證。 該方法是通用的,因此它可以接受通用的類型。 您不需要在方法中使用T參數,因為它足以了解BaseClaimResponseDataContract部分。

通常,泛型用於保存類型信息並使其流動。 您從列表中獲得了相同的類型。

在你的情況下,這是不明顯的。 除了關閉泛型類型之外, T似乎未被使用。

也許BaseClaimResponseDataContract<T>沒有有用的非泛型基類。 您不能使用開放泛型類型,因此必須使用泛型類型參數將其關閉。

是否在方法中使用T無關緊要。 我們可以有這樣的通用函數:

int dummy<T> (List<T> a)
{
    return a.Count * 2;
}

正如您所看到的,T不會在方法中的任何位置使用。您的示例也可能是這樣的。 如果您需要更多解釋,請繼續閱讀:以這種方式查看:您有一個泛型類型,並且您想要編寫一個帶有這種類型參數的方法,這里是BaseClaimResponseDataContract <>。 現在,您可以編寫不同的方法,每個方法用於此類型的具體實例,例如

public void ValidateExceptionFromResponse( BaseClaimResponseDataContract<int> response ) 
{ ... }
public void ValidateExceptionFromResponse( BaseClaimResponseDataContract<float> response ) 
{ ... }
public void ValidateExceptionFromResponse( BaseClaimResponseDataContract<String> response ) 
{ ... }

這當然效率不高,或者讓方法成為通用方法,即可以采用由所有類型制作的BaseClaimResponseDataContract <>實例。 我們稱之為T型,然后我們就可以寫了

public void ValidateExceptionFromResponse<T>( BaseClaimResponseDataContract<T> response )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM