Как сделать класс универсальным для передачи динамического класса свойств в 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();
}
}