如何使 class 通用以在 c# 中传递动态 属性 class

How to make class generic to pass dynamic property class in c#

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

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 class。我怎样才能避免这种情况?我怎样才能使这个 class 通用,这样我就可以传递多个 class 像 Test 来忽略 Extra 属性?

class CsvClassMap<T> where T:Test1,class 
{
    //your class logic
}

你的意思是这样的吗?

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();

    }
}

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

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

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");
            }
        });

而不是使用 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();
    }
}