C# 创建泛型方法

C# 创建泛型方法,c#,generics,C#,Generics,我正在尝试为以下代码创建一个通用方法: foreach (var glitter in glitterpurchase.GlitterPurchaseDetails) { var glitterInventory = _db.GlitterInventoriesRepository.GetAll(m => m.GlitterId == glitter.GlitterId); if (!glitterInventory.Any()) { var new

我正在尝试为以下代码创建一个通用方法:

foreach (var glitter in glitterpurchase.GlitterPurchaseDetails)
{
    var glitterInventory = _db.GlitterInventoriesRepository.GetAll(m => m.GlitterId == glitter.GlitterId);
    if (!glitterInventory.Any())
    {
        var newInventory = new GlitterInventory
        {
            GlitterId = glitter.GlitterId,
            Quantity = glitter.Quantity,
            TotalAmount = (decimal)glitter.Quantity * glitter.UnitPrice,
            UnitPrice = glitter.UnitPrice,
            CreatedBy = User.Identity.Name,
            CreatedDate = DateTime.Now,
        };
        _db.GlitterInventoriesRepository.Insert(newInventory);
    }
    else                    
    {
        var updateInventory = glitterInventory.First();
        updateInventory.Quantity += glitter.Quantity;
        updateInventory.TotalAmount += (decimal)glitter.Quantity * glitter.UnitPrice;
        updateInventory.UnitPrice = (decimal)updateInventory.Quantity / updateInventory.TotalAmount;
        updateInventory.UpdatedBy = User.Identity.Name;
        updateInventory.UpdatedDate = DateTime.Now;
        _db.GlitterInventoriesRepository.Update(updateInventory);
    }
}
public virtual void UpdateInventory<PurchasedEntity, Inventory>(IEnumerable<PurchasedEntity> purchaseDetails, GenericRepository<Inventory> inventory, Expression<Func<Inventory, bool>> filterForInventory) 
            where PurchasedEntity : class
            where Inventory : class

{
    foreach (var item in purchaseDetails)
    {
        var glitterInventory = inventory.GetAll(filterForInventory);
        if (!glitterInventory.Any())
        {
            var newInventory = (Inventory)Activator.CreateInstance(typeof(Inventory), new object[] 
            {
                GlitterId = item.GlitterId,
                Quantity = item.Quantity,
                TotalPrice = (decimal)item.Quantity * item.UnitPrice,
                UnitPrice = item.UnitPrice,
                CreatedBy = User.Identity.Name,
                CreatedDate = DateTime.Now,
            });

            inventory.Insert(newInventory);
        }
        else
        {
            var updateInventory = glitterInventory.First();
            updateInventory.Quantity += item.Quantity;
            updateInventory.TotalAmount += (decimal)item.Quantity * item.UnitPrice;
            updateInventory.UnitPrice = (decimal)updateInventory.Quantity / updateInventory.TotalAmount;
            updateInventory.UpdatedBy = User.Identity.Name;
            updateInventory.UpdatedDate = DateTime.Now;
            inventory.Update(updateInventory);
        }
    }
}
上面的代码只是简单地更新库存。我想创建一个通用方法,这样我就可以调用该方法并更新不同项目(类)的清单。我不擅长泛型,经过研究,我编写了以下代码:

foreach (var glitter in glitterpurchase.GlitterPurchaseDetails)
{
    var glitterInventory = _db.GlitterInventoriesRepository.GetAll(m => m.GlitterId == glitter.GlitterId);
    if (!glitterInventory.Any())
    {
        var newInventory = new GlitterInventory
        {
            GlitterId = glitter.GlitterId,
            Quantity = glitter.Quantity,
            TotalAmount = (decimal)glitter.Quantity * glitter.UnitPrice,
            UnitPrice = glitter.UnitPrice,
            CreatedBy = User.Identity.Name,
            CreatedDate = DateTime.Now,
        };
        _db.GlitterInventoriesRepository.Insert(newInventory);
    }
    else                    
    {
        var updateInventory = glitterInventory.First();
        updateInventory.Quantity += glitter.Quantity;
        updateInventory.TotalAmount += (decimal)glitter.Quantity * glitter.UnitPrice;
        updateInventory.UnitPrice = (decimal)updateInventory.Quantity / updateInventory.TotalAmount;
        updateInventory.UpdatedBy = User.Identity.Name;
        updateInventory.UpdatedDate = DateTime.Now;
        _db.GlitterInventoriesRepository.Update(updateInventory);
    }
}
public virtual void UpdateInventory<PurchasedEntity, Inventory>(IEnumerable<PurchasedEntity> purchaseDetails, GenericRepository<Inventory> inventory, Expression<Func<Inventory, bool>> filterForInventory) 
            where PurchasedEntity : class
            where Inventory : class

{
    foreach (var item in purchaseDetails)
    {
        var glitterInventory = inventory.GetAll(filterForInventory);
        if (!glitterInventory.Any())
        {
            var newInventory = (Inventory)Activator.CreateInstance(typeof(Inventory), new object[] 
            {
                GlitterId = item.GlitterId,
                Quantity = item.Quantity,
                TotalPrice = (decimal)item.Quantity * item.UnitPrice,
                UnitPrice = item.UnitPrice,
                CreatedBy = User.Identity.Name,
                CreatedDate = DateTime.Now,
            });

            inventory.Insert(newInventory);
        }
        else
        {
            var updateInventory = glitterInventory.First();
            updateInventory.Quantity += item.Quantity;
            updateInventory.TotalAmount += (decimal)item.Quantity * item.UnitPrice;
            updateInventory.UnitPrice = (decimal)updateInventory.Quantity / updateInventory.TotalAmount;
            updateInventory.UpdatedBy = User.Identity.Name;
            updateInventory.UpdatedDate = DateTime.Now;
            inventory.Update(updateInventory);
        }
    }
}
如何删除此错误并获得类的一般属性?


我甚至不知道我写的代码是否好,所以如果你能改进它,那就太好了。谢谢。

我假设不是每一个
购买身份都有
GlitterId
(可能不应该取决于你的域名)。因此,在
PurchasedEntity
上定义合适的
Id
属性(或者更好地将其提取到接口):

更新
库存
以实现
ipourchasedentity

public class GlitterInventory : IPurchasedEntity{
     Guid IPurchasedEntity.Id { get{ return GlitterId; }}
}
然后您的
UpdateInventory
方法应该读取
Id
,而不是
Id

public virtual void UpdateInventory<PurchasedEntity, Inventory>(
   IEnumerable<PurchasedEntity> purchaseDetails, 
   GenericRepository<Inventory> inventory, 
   Expression<Func<Inventory, bool>> filterForInventory) 
        where PurchasedEntity : IPurchasedEntity, class
        where Inventory : IPurchasedEntity, class, new()
{
    foreach (var item in purchaseDetails)
    {
        var inventory = new Inventory();
        inventory.Id = item.Id;
       // if you have more standard fields, define them in IPurchasedEntity
    }
}
公共虚拟空间更新Inventory(
i无数的采购详情,
一般存储库存,
表达式过滤器(用于存储)
何处购买身份:I购买身份,类别
其中库存:IPURCHASENDETITY、class、new()
{
foreach(purchaseDetails中的var项目)
{
var存货=新存货();
inventory.Id=item.Id;
//如果有更多的标准字段,请在IPURCHASENDITY中定义它们
}
}

更新:在尝试从
PurcahsedEntity
Inventory
推断您的域之后,调用
ipourchasedentity
IInventory
并在那里定义您的公共属性可能更有意义。

您已经定义了一个通用参数约束
其中PurchasedEntity:类
,这意味着允许它为此泛型参数使用任何类型。因此,在处理项变量时,泛型方法只能使用对象类提供的方法、属性和字段,因为对象类是所有类型中最小的公分母。。。您需要指定约束,使其仅限于声明ID、数量、单价等的(基类)类。。。财产。然后编译器将接受代码。@elgonzo我可以创建一个包含Quantity、TotalPrice、UnitPrice、CreatedBy、CreatedDate的基类,但是GlitterId应该是泛型的,因为GlitterId可以是PowderId、ColorId等等。我有很多库存项目,我正在尝试编写一个通用方法,可以用于所有这些项目。GlitterId是属性的名称,而不是类型。您不能使用泛型参数来“交换”属性的名称…因此,是否没有办法实现我想要的?你能给我一些可能解决我的问题的建议吗/当然有解决这个问题的方法,但我真的不知道什么最适合你的需要。。。例如,您可以让您的基类声明一个“通用”ID属性,并且您的每个具体实现(Glitter、Powder等)都将该ID属性设置为Glitter、PowderID或其他任何属性。如有必要,您可以保留GlitterID、PowderID等属性,并进行类实现,以便它们的值始终与基类中声明的ID属性同步……非常感谢,@elgonzo也提出了同样的建议,您可以查看我们的聊天。我接受这个答案,但如果elgonzo在这里写了一个答案,那么我会把这个标记为答案,因为他真的花了一些时间和我一起解决这个问题。。。