[英]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.