我能够理解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;
}
}
答案 0 :(得分:6)
在这种情况下,泛型参数的唯一目的似乎是强制该方法的参数必须是BaseClaimResponseDataContract<T>
。我怀疑你的解决方案中有多种类型从中继承,例如:
public class SomeSample : BaseClaimResponseDataContract<AnotherClass>
{
}
只能使用实现此基类型的实例调用该方法,因此它类似于使用接口标记类的形式。
答案 1 :(得分:2)
该方法是通用的,因为它采用通用参数。为了指定参数的类型,使用泛型,这意味着该方法本身采用泛型参数。
答案 2 :(得分:2)
在这种情况下,这不是方法,而是泛型:它是论证。该方法是通用的,因此它可以接受通用的类型。您不需要在方法中使用T
参数,因为它足以了解BaseClaimResponseDataContract
部分。
答案 3 :(得分:0)
通常,泛型用于保存类型信息并使其流动。您从列表中获得了相同的类型。
在你的情况下,这是不明显的。除了关闭泛型类型外,T
似乎未被使用。
也许BaseClaimResponseDataContract<T>
没有有用的非通用基类。您不能使用开放泛型类型,因此必须使用泛型类型参数关闭它。
答案 4 :(得分:0)
方法中是否使用T无关紧要。我们可以有这样的通用函数:
int dummy<T> (List<T> a)
{
return a.Count * 2;
}
正如您所看到的,T不会在方法中的任何位置使用。您的示例也可能是这样的。如果您需要更多解释,请继续阅读: 以这种方式看待它:你有一个泛型类型,并且你想要编写一个带有这种类型参数的方法,这里是BaseClaimResponseDataContract&lt;&gt ;.现在,您可以编写不同的方法,每种方法用于此类型的具体实例,例如
public void ValidateExceptionFromResponse( BaseClaimResponseDataContract<int> response )
{ ... }
public void ValidateExceptionFromResponse( BaseClaimResponseDataContract<float> response )
{ ... }
public void ValidateExceptionFromResponse( BaseClaimResponseDataContract<String> response )
{ ... }
当然效率不高,或者让方法是通用方法,即可以采用BaseClaimResponseDataContract&lt;&gt;的实例。各种类型的。我们称这个类型为T,然后我们可以写
public void ValidateExceptionFromResponse<T>( BaseClaimResponseDataContract<T> response )