无法理解C#泛型

时间:2014-01-15 22:22:24

标签: 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;
    }
}

5 个答案:

答案 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 )