Как сделать класс универсальным для передачи динамического класса свойств в C#

У меня есть демо-код, который игнорирует 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 имущество?

4 ответа

Решение

Ты имеешь в виду что-то подобное?

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 CsvClassMap<T> where T:Test1,class 
{
    //your class logic
}

Хорошо, это может сработать и помочь вам на некоторое время, если вы не добавите больше свойств или ваш интерфейс класса останется стабильным.

Кроме того, я бы предложил усилить вашу реализацию, добавив пользовательский атрибут и используя отражение, чтобы определить, какие свойства игнорировать. Вот некоторый код, чтобы дать вам идею:

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();
    }
}
Другие вопросы по тегам