具有计算性质的C#DTO

具有计算性质的C#DTO,c#,inheritance,interface,dto,C#,Inheritance,Interface,Dto,我有一些DTO需要保存到redis,我希望它们都有一个属性或方法来生成redis的密钥 public class Product { public string Name {get; set;} public string Type {get; set;} // Use Property (Maybe Inherit a base class or interface) public string CacheKey { get {

我有一些DTO需要保存到redis,我希望它们都有一个属性或方法来生成redis的密钥

public class Product
{
   public string Name {get; set;}
   public string Type {get; set;}

   // Use Property (Maybe Inherit a base class or interface)
   public string CacheKey
   {
      get
      {
         return Type + "_" + Name;
      }
   }

   // User Method (Maybe Inherit a base class or interface)
   public string GetCacheKey()
   {
      return Type + "_" + Name;
   }
}
或者。。。我不应该将它们添加到DTO,但我希望所有需要保存到redis的DTO都必须有一个密钥,并且每个密钥都是由其自身的属性生成的

有人能给我一些建议吗?

观察一下

您不应该改变DTO的既定目的(正如@GlennvanAcker所说的DTO没有逻辑)

然而,我们可以给它一个扩展方法。。。这就是我的建议

    public static class ProductExtensions
    {
        public static string CacheKey(this Product product)
        {
            return product.Type + "_" + product.Name;
        }
    }
@HansKesting指出,除了Product,我没有展示如何使这个类工作

这需要我们扩展基类或接口。如果此方法要应用于多个类;编译器需要知道类具有所需的属性(类型和名称):

e、 g


我们必须在这方面务实思考。在这种情况下,缓存键getter函数的实现不是真正的业务逻辑

我的建议是,创建一个接口,并使用cache key getter函数在任何需要它的DTO中实现它


一种绝对有效的实用方法。

通常,DTO是一个数据传输对象,它不包括逻辑。但您始终可以添加带有GetCacheKey方法的基类,并从中继承。然后,您不需要在任何地方都包含该代码,您应该创建ViewModel或其他与DTO不同的东西。Becuz DTO不应该包含logic我同意@GlennvanAcker,用这个逻辑创建一个基类并继承它,在需要的地方在类中重写它。DTO通常不包含逻辑,但所有类都有一个与之关联的ToString和Hash函数…@Gary如果没有真正通用的方法来构建密钥,那么您可以覆盖DTO中的基类函数,或者创建一个所有DTO都实现的接口。当您在几个月内查看代码时,从最有意义的角度来看待它,并且它是最容易支持的。@NguyễnVănPhong的评论强调,在某种程度上,这正在成为一个语义论点。这里正确的问题不是这是否适用于DTO,而是这是否适用于您的类型,不管我们使用什么标签来描述它。DTO通常不包含逻辑显然有很好的理由,但如果您总是反序列化回同一类型,那么将其视为最一般、平台无关意义上的DTO可能没有用。扩展方法需要特定的类、基类或接口。OP希望为许多不相关的类提供此功能。
// I'm not calling this interface IDto because I am not assuming that all DTOs have these properties.
public interface IDtoWithTypeAndName
{
    public string Type { get; set; }
    public string Name { get; set; }
}

public static class DtoExtensions
{
    public static string CacheKey(this IDtoWithTypeAndName dto)
    {
        return dto.Type + "_" + dto.Name;
    }
}
public class Product : IDtoWithTypeAndName
{
    public string Type { get; set; }
    public string Name { get; set; }
}