如何有一些动态类的概念
本文关键字:动态 | 更新日期: 2023-09-27 18:23:52
我有两个类A和B。它们都有最常见的属性,都有几个不同的字段。现在根据某些条件使用类中的任意一个。使用它们的共同属性。我无法更改使用继承的模式。
例如
public class A
{
public string field1 { get; set; };
public string field2 { get; set; };
public string field3 { get; set; };
public string field4 { get; set; };
public string field5 { get; set; };
public string field6 { get; set; };
public string field7 { get; set; };
public string field8 { get; set; };
public string anotherA1 { get; set; };
public string anotherA2 { get; set; };
}
public class B
{
public string field1 { get; set; };
public string field2 { get; set; };
public string field3 { get; set; };
public string field4 { get; set; };
public string field5 { get; set; };
public string field6 { get; set; };
public string field7 { get; set; };
public string field8 { get; set; };
public string anotherB1 { get; set; };
public string anotherB2 { get; set; };
}
A a = new A();
B b = new B();
dynamic d;
if(isDo)
d= a;
else
d= b;
string strField = d.field1;
string test = d.field3;
请告诉我实现这一目标的最佳方式。
如果您想从一个类型映射到另一个类型,其中类型通过继承而不相关,但具有许多常用名称的属性,则可以使用AutoMapper。
可以使用NuGet将AutoMapper添加到项目中。对于您的示例类,您可以像这样从一个映射到另一个:
using System;
namespace Demo
{
public class A
{
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
public string field4 { get; set; }
public string field5 { get; set; }
public string field6 { get; set; }
public string field7 { get; set; }
public string field8 { get; set; }
public string anotherA1 { get; set; }
public string anotherA2 { get; set; }
}
public class B
{
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
public string field4 { get; set; }
public string field5 { get; set; }
public string field6 { get; set; }
public string field7 { get; set; }
public string field8 { get; set; }
public string anotherB1 { get; set; }
public string anotherB2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
A a = new A {field1 = "A1", field2 = "A2", field3 = "A3"};
AutoMapper.Mapper.CreateMap<A, B>();
B b = AutoMapper.Mapper.Map<B>(a); // Copies fields from a to b
Console.WriteLine(b.field1); // Prints "A1"
}
}
}
如果不能修改基类,可以创建实现公共接口的新子类。但是您必须复制构造函数中的属性值。
void Main()
{
var a = new A(){ Name = "A" };
var b = new B(){ Name = "B" };
INameProvider provider = new BNext(b);
//...
}
//original classes
public class A{
public string Name { get; set; }
}
public class B{
public string Name { get; set; }
public string Id { get; set; }
}
//common interface
public interface INameProvider {
string Name { get; set; }
}
//adapters
public class ANext : A, INameProvider
{
public ANext(A a)
{
this.Name = a.Name;
}
}
public class BNext : B, INameProvider
{
public BNext(B b)
{
this.Name = b.Name;
this.Id = b.Id;
}
}
您应该在OOP:中学习继承
public class Common
{
public string field1 { get; set; };
public string field2 { get; set; };
public string field3 { get; set; };
public string field4 { get; set; };
public string field5 { get; set; };
public string field6 { get; set; };
public string field7 { get; set; };
public string field8 { get; set; };
}
public class A : Common
{
public string anotherA1 { get; set; };
public string anotherA2 { get; set; };
}
public class B : Common
{
public string anotherB1 { get; set; };
public string anotherB2 { get; set; };
}
A a = new A();
B b = new B();
Common d;
if(isDo)
d= a;
else
d= b;
string strField = d.field1;
string test = d.field3;
如果您不能修改类本身,并且您绝对想要一个通用接口,那么您需要编写自己的Adapters。
我认为您的问题最好通过完全抛弃dynamic
并使用接口来解决。
public interface IFoo
{
string field1 { get; set; }
string field2 { get; set; }
string field3 { get; set; }
//etc...
}
public class A : IFoo
{
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
//...etc
public string anotherA1 { get; set; }
public string anotherA2 { get; set; }
}
public class B : IFoo
{
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
//...etc
public string anotherB1 { get; set; }
public string anotherB2 { get; set; }
}
所以现在你可以:
IFoo obj = isDo ? (IFoo)new A() : (IFoo)new B();
string strField = d.field1;
string test = d.field3;