如何有一些动态类的概念

本文关键字:动态 | 更新日期: 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;