【问题标题】:How to make class generic to pass dynamic property class in c#如何使类泛型以在 C# 中传递动态属性类
【发布时间】:2018-07-13 13:05:28
【问题描述】:

我有忽略Extra 属性的演示代码。我需要使这个类通用。

public class HelloFriend 
{
    public static void Main(string[] args)
    {
        var s = new StringBuilder();
        s.Append("Id,Name\r\n");
        s.Append("1,one\r\n");
        s.Append("2,two\r\n");
        using (var reader = new StringReader(s.ToString()))
        using (var csv = new CsvReader(reader))
        {
            csv.Configuration.RegisterClassMap<TestMap>();
            csv.GetRecords<Test>().ToList();
        }
    }
}

public class Test : Test1
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public abstract class Test1
{
    public decimal Extra { get; set; }
}

public class TestMap : CsvClassMap<Test>
{
    public TestMap()
    {
        AutoMap();
        Map(m => m.Extra).Ignore();
    }
}

如上代码所示,如​​果我需要使用不同的Test1,或者Test2而不是Test,那么我需要编写另一个TestMap类。我怎样才能避免这种情况?我怎样才能使这个类通用,所以我可以传递多个类如Test 来忽略Extra 属性?

【问题讨论】:

    标签: c# csvhelper


    【解决方案1】:
    class CsvClassMap<T> where T:Test1,class 
    {
        //your class logic
    }
    

    【讨论】:

      【解决方案2】:

      你的意思是这样的吗?

      class Program
      {
          public static void Main(string[] args)
          {
              var s = new StringBuilder();
              s.Append("Id,Name\r\n");
              s.Append("1,one\r\n");
              s.Append("2,two\r\n");
              using (var reader = new StringReader(s.ToString()))
              using (var csv = new CsvReader(reader))
              {
                  csv.Configuration.RegisterClassMap<TestMap<Test>>();
                  csv.GetRecords<Test>().ToList();
              }
          }
      }
      public class Test : Test1
      {
          public int Id { get; set; }
          public string Name { get; set; }
      
      }
      
      public Abstract class Test1 
      {
         public decimal Extra { get; set; }
      }
      
      
      public class Test2 : Test1
      {
          //other propertys
      }
      
      
      public class TestMap<T> : CsvClassMap<T> where T : Test1
      {
          public TestMap()
          {
              AutoMap();
      
                  Map(m => m.Extra).Ignore();
      
          }
      }
      

      【讨论】:

      • 是的,类似这样的事情,但在 TestMap 类中,我想避免两次声明 Test1 和 Test 2 ,它必须是通用的,所以我们可以传递任何类来忽略该属性
      • @Tiger 是否总是相同的属性(“Extra”)?
      • 好的,我更新了我的 anwser。我不确定这是否真的是你的意思。现在每个继承自 Test 的类都会忽略这个“额外”属性。
      • 以下代码有效。'public class TestMap : CsvClassMap where T : Test1 { public TestMap() { AutoMap();地图(m => m.Extra).Ignore(); } }'
      • 谢谢@Darem 我从你的回答中得到了灵感
      【解决方案3】:

      好的,只要您不添加更多属性或您的类接口保持稳定,它可能会工作并帮助您一段时间。

      此外,我建议通过添加自定义属性并使用反射来检测要忽略的属性来加强您的实施。这里有一些代码可以给你一个想法:

      public class ToBeIgnoredAttribute:Attribute
      {
      
      }
      
      public class Test
      {
          public int Property1 { get; set; }
      
          [ToBeIgnored]
          public int Property2 { get; set; }
      
      }
      var type= typeof(Test)// or typeof(T);
      type.GetProperties().ForEach(prop =>
      {
      
                  if (prop.GetCustomAttribute<ToBeIgnoredAttribute>() != null)
                  {
                    Console.WriteLine($"//Call Map with right overload e.g with property name string {prop.Name}"); 
                  }
                  else
                  {
                      Console.WriteLine($"{prop.Name} is not ignored");
                  }
              });
      

      【讨论】:

        【解决方案4】:

        不要使用AutoMap,只映射你想要映射的属性。

        public class TestMap : ClassMap<Test>
        {
            public TestMap()
            {
                Map(m => m.Id);
                Map(m => m.Name);
            }
        }
        

        另一种选择是向属性添加属性。

        public abstract class Test1
        {
            [Ignore]
            public decimal Extra { get; set; }
        }
        
        public class TestMap : ClassMap<Test>
        {
            public TestMap()
            {
                AutoMap();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-24
          • 1970-01-01
          • 2020-02-05
          • 1970-01-01
          • 2011-08-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多