Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Making method as generic causes error: The type 'T' cannot be used as type parameter 'T' in the generic type or method

I created a method GetArticlePriceDefinedInErpPricePolicyAsync, previously I had 4 versions of this method which was not good for maintance, one change caused editing 4 methods which were actually same, and it was bad concept since I would keep identical code x4.

The reason why I would like to write this method as generic is because there are 4 different classes that are using this method (webShopArticles can be 4 different classes).

Purpose of this method is to receive list of some Dto’s and to return modified prices.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

And solution to this could be to create this method as a generic so I could have only one method in my app instead of 4 same methods.

It would be much more easy to maintain the app etc.

Here is my code:

public async Task<List<T>> GetArticlePriceDefinedInErpPricePolicyAsync<T>(List<T> webShopArticles, Guid? externalCompanyId, CancellationToken cancellationToken)
{
    var externalArticleIds = webShopArticles
        .Where(x => GetPropertyValue<Guid?>(x, "ErpArticleId").HasValue)
        .Select(x => GetPropertyValue<Guid>(x, "ErpArticleId"))
        .ToArray();
        
    var pricePolicyItems = new List<PricesRelatedToPricePolicy>();

    var articlesFromPricePolicy = await _dbContext.ErpPricePolicyItems
        .Where(x => externalArticleIds.Contains(GetPropertyValue<Guid>(x, "ExternalArticleId")))
        .Select(x => new PricesRelatedToPricePolicy
        {
            Id = x.Id,
            ErpArticleId = GetPropertyValue<Guid>(x, "ExternalArticleId"),
            Priority = x.Priority,
            PolicyTypeEnum = x.PolicyType,
            Price = x.Price,
            Discount1 = x.Discount1,
            Discount2 = x.Discount2,
            Discount3 = x.Discount3
        })
        .ToArrayAsync(cancellationToken);

    pricePolicyItems.AddRange(articlesFromPricePolicy);
    
    if (!pricePolicyItems.Any())
        return webShopArticles;
  
    ArticleMatching(webShopArticles, articlesFromPricePolicy);

    return webShopArticles;
}


private List<T> ArticleMatching<T>(List<T> articles, PricesRelatedToPricePolicy[] articlesDefinedInPricesPolicy) where T : IErpPricePolicySyncProps
{
    if (articlesDefinedInPricesPolicy[0] == null)
        return articles;

    foreach (var item in articles.Where(x => !x.MatchedPP.HasValue && x.ExternalSytemArticleId.HasValue))
    {
        var articleDefinedInPolicyPrice = articlesDefinedInPricesPolicy
            .Where(x => x.ExternalSytemArticleId.HasValue && (x.ExternalSytemArticleId == item.ExternalSytemArticleId))
            .FirstOrDefault();

        item.Price = CalculateArticlePriceBasedOnPricePolicy(articleDefinedInPolicyPrice, item);
        item.MatchedPP = articlesDefinedInPricesPolicy.Any(x => item.ExternalSytemArticleId.HasValue && x.ExternalSytemArticleId.Value == item.ExternalSytemArticleId.Value);
    }

    return articles;
}

But I am getting this error:

Error CS0314 The type ‘T’ cannot be used as type parameter ‘T’ in the generic type or method ‘PricePolicyCalculationService.ArticleMatching(List, PricesRelatedToPricePolicy[])’. There is no boxing conversion or type parameter conversion from ‘T’ to ‘Common.Dtos.Interfaces.IErpPricePolicySyncProps’.

IErpPricePolicySyncProps is interface that inheriting classes that will use this generic method

 public interface IErpPricePolicySyncProps
 {
        public Guid? ErpArticleId { get; set; }
        public Guid? ErpCategoryId { get; set; }
        public Guid? ErpSubCategoryId { get; set; }
        public Guid? ErpBrandId { get; set; }
        public decimal Price { get; set; }
        public bool? MatchedPP { get; set; }
 }

Thanks in advance,
Cheers

>Solution :

The ArticleMatching method expects the object you pass in to implement the IErpPricePolicySyncProps interface. If you look at it, it will be something like this:

public void ArticleMatching<T>(List<T> articles, ...)
    where T : IErpPricePolicySyncProps

So to fix this, you also need to mark your method in the same way:

public async Task<List<T>> GetArticlePriceDefinedInErpPricePolicyAsync<T>(List<T> webShopArticles, Guid? externalCompanyId, CancellationToken cancellationToken)
    where T : IErpPricePolicySyncProps
{
    ...
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading