简体   繁体   English

如何使类泛型在c#中传递动态属性类

[英]How to make class generic to pass dynamic property class in c#

I have demo code which ignores the Extra property. 我有演示代码忽略Extra属性。 I need to make this class generic. 我需要使这个类通用。

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

As shown in above code if I need to use different Test1 , or Test2 instead of Test, then I need to write another TestMap class. 如上面的代码所示,如​​果我需要使用不同的Test1Test2而不是Test,那么我需要编写另一个TestMap类。 How can I avoid this? 我怎么能避免这个? How can I make this class generic, so I can pass multiple classes like Test to ignore the Extra property? 如何使这个类通用,所以我可以传递像Test这样的多个类来忽略Extra属性?

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

Do you mean somehting like this? 你的意思是这样的吗?

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

    }
}

Ok, it might work and help you for a while as long as you do not add more properties or your class interface stays stable. 好吧,只要你不添加更多属性或者你的类界面保持稳定,它可能会工作并帮助你一段时间。

Besides, i'd suggest to reinforce your implementation by adding custom attribute and using reflection to detect which properties to ignore. 此外,我建议通过添加自定义属性和使用反射来检测要忽略的属性来强化您的实现。 Here is some code to give you an idea: 这里有一些代码可以给你一个想法:

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

Instead of using AutoMap , only map the properties you want to be mapped. 而不是使用AutoMap ,只映射您要映射的属性。

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

Another option is to add an attribute to the property. 另一种选择是向属性添加属性。

public abstract class Test1
{
    [Ignore]
    public decimal Extra { get; set; }
}

public class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        AutoMap();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM