如何在c#中获取类的基类

本文关键字:基类 获取 | 更新日期: 2023-09-27 18:24:30

问题的标题在实际场景中可能有不同的含义
简史:

我们有在azure表中执行CRUD操作的现有代码。但它只能对同一类类型执行InserOrMergeBatch。我需要的是一个方法,只要它们有相同的基类,就可以添加不同类型的类。分区键应该不是问题,因为它是以其他方式处理的。

所以问题来了。

  1. 创建一个可以为特定基类创建队列的类
  2. 创建的类必须能够添加任何类型的对象,只要它具有所需的基类

例如,我有这两个基类:人类和动物

public class Human
{
    public int Height { get; set; }
    public int Weight { get; set; }
}  
public class Animal
{
    public string Breed { get; set; }
    public string Family { get; set; }
}  

其他类别使用:

public class Eye : Human
{
    public string Color { get; set; }
}
public class Nose : Human
{
    public string Type { get; set; }
}
public class Teeth : Human
{
    public int Count { get; set; }
}  
public class Dog : Animal
{
    public string NoseColor { get; set; }
}
public class Cat : Animal
{
    public string EyeColor { get; set; }
}  

第一个问题是创建一个具有一些必需方法的类:

public class AzureTableBatchCrud
{
    public void CreateQueue( /* Specify the type of base class. */ )
    {
    }
    public void AddQueue( /* Accept single object or list of objects of any type */ )
    {
        /* Must ensure that the added objects are inherited on same base class */
    }
    public bool ExecuteQueue()
    {
        /* Insert or merge objects on azure table */
        return false;
    }
}  

为了更清楚,让我们使用这个类:

public class SampleUsage
{
    public void SampleInsert()
    {
        // Example 1: Creating AzureTableBatchCrud with base class 'Human'
        AzureTableBatchCrud sample1 = new AzureTableBatchCrud();
        sample1.CreateQueue(Human);
        // Right! because their base class is 'Human'
        Eye eye1 = new Eye();
        Nose nose1 = new Nose();
        Teeth teeth1 = new Teeth();
        sample1.AddQueue(eye1);
        sample1.AddQueue(nose1);
        sample1.AddQueue(teeth1);
        // Wrong! because base class is not 'Human'
        Dog dog1 = new Dog();
        Cat cat1 = new Cat();
        sample1.AddQueue(dog1); // must throw error
        sample1.AddQueue(cat1); // must throw error

        // Example 2: Creating AzureTableBatchCrud with base class 'Animal'
        AzureTableBatchCrud sample2 = new AzureTableBatchCrud();
        sample2.CreateQueue(Animal);
        // Right! because base class is 'Animal'
        Dog dog2 = new Dog();
        Cat cat3 = new Cat();
        sample2.AddQueue(dog2);
        sample2.AddQueue(cat2);
        // Wrong! because base class is not 'Animal'
        Eye eye2 = new Eye();
        Teeth teeth2 = new Teeth();
        sample2.AddQueue(eye2);     // must throw error
        sample2.AddQueue(teeth2);   // must throw error
    }
}  

希望这个例子能说明问题的概念。

我只知道C#中的基本编码,就这一点而言,这是一种非常先进的编码。我完全不知道。如有任何帮助,我们将不胜感激。

更新
我想我需要AzureTableBatchCrud类的示例代码。

更新2

我发布这段代码是为了让读者对这个问题有更多的了解。我还没有测试过这个代码,但我会在它工作后尽快发布答案,这样未来可能遇到同样问题的读者就可以参考了。

namespace ProjectName.Domain.Entities
{
    [DataContract]
    public class NoSQLEntity: TableEntity
    {
        public NoSQLEntity()
        {
        }
        public NoSQLEntity(string partitionKey, string rowKey)
        {
            PartitionKey = partitionKey;
            RowKey = rowKey;
        }
    }
}
namespace ProjectName.Domain.Attribute
{
    [System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = false)]
    public class AzureProjectionTable: System.Attribute
    {
        public string table;
    }
}
namespace ProjectName.Data.DAOs
{
    public class CrudBatch<T> where T : NoSQLEntity
    {
        private WomContext<T> _context;
        CloudTable azuretable;
        string table;
        TableBatchOperation batchOperation;
        List<T> itemlist;
        public CrudBatch()
        {
            CloudStorageAccount storageAccount = ConfigWrapper.DataConnectionString();
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
            var attrs = (Domain.Attribute.AzureProjectionTable[])
                            typeof(T).GetCustomAttributes(typeof(Domain.Attribute.AzureProjectionTable), true);
            if (attrs.Length > 0)
                table = attrs[0].table;
            azuretable = tableClient.GetTableReference(table);
            _context = new WomContext<T>(tableClient, table);
            batchOperation = new TableBatchOperation();
            itemlist = new List<T>();
        }
        public void AddQueue(object item)
        {
            var attrs = (Domain.Attribute.AzureProjectionTable[])
                            item.GetType().GetCustomAttributes(typeof(Domain.Attribute.AzureProjectionTable), true);
            if (attrs.Length > 0)
            {
                if (table.Equals(attrs[0].table))
                {
                    itemlist.Add((T)item);
                }
            }
        }
        public void AddQueue(List<object> item)
        {
            foreach (var i in item)
            {
                var attrs = (Domain.Attribute.AzureProjectionTable[])
                                i.GetType().GetCustomAttributes(typeof(Domain.Attribute.AzureProjectionTable), true);
                if (attrs.Length > 0)
                {
                    if (table.Equals(attrs[0].table))
                    {
                        itemlist.Add((T)i);
                    }
                }
            }
        }
        public bool ExecuteQueue(CrudAction action)
        {
            switch (action)
            {
                case CrudAction.InsertOrMergeBatch: return InsertOrMergeBatch();
                case CrudAction.DeleteBatch: return DeleteBatch();
                default: return false;
            }
        }
        public void ClearQueue()
        {
            itemlist.Clear();
        }
        public T Get(string partitionKey, string rowKey)
        {
            TableOperation retrieve = TableOperation.Retrieve<T>(partitionKey, rowKey);
            return (T)azuretable.Execute(retrieve).Result;
        }
        public IQueryable<T> Table()
        {
            return _context.Table;
        }
        private bool InsertOrMergeBatch()
        {
            foreach (var value in itemlist)
            {
                batchOperation.InsertOrMerge(value);
            }
            azuretable.ExecuteBatch(batchOperation).ToList();
            return true;
        }
        private bool DeleteBatch()
        {
            TableBatchOperation batchOperation = new TableBatchOperation();
            T deleteEntity;
            foreach (var value in itemlist)
            {
                TableOperation retrieve = TableOperation.Retrieve<T>(value.PartitionKey, value.RowKey);
                deleteEntity = (T)azuretable.Execute(retrieve).Result;
                if (deleteEntity != null)
                {
                    batchOperation.Delete(deleteEntity);
                }
            }
            azuretable.ExecuteBatch(batchOperation);
            return true;
        }
    }
    public enum CrudAction
    {
        InsertOrMergeBatch,
        DeleteBatch
    }
}
namespace ProjectName.Data.Context
{
    public class WomContext<T> : TableServiceContext where T: NoSQLEntity
    {
        private string table;
        public WomContext(CloudTableClient client, string tablename)
            : base(client)
        {
            table = tablename;
        }
        public TableServiceQuery<T> Table
        {
            get
            {
                return this.CreateQuery<T>(table).AsTableServiceQuery(this);
            }
        }
    }
}  

一个样本基类可以是:

namespace ProjectName.Domain.Entities.Carts
{
    [Attribute.AzureProjectionTable(table = BaseTableNames.Cart)]
    public class Cart: NoSQLEntity
    {
        public Cart() : base()
        {
        }
        public Cart(string partitionkey, string rowkey) 
            : base(partitionkey, rowkey)
        {
        }
        // Some properties...
    }
}

如何在c#中获取类的基类

您可以像这样简单地获得基类:

Type baseClass = childClassObject.GetType().BaseType;

如果我没看错你的问题,你在寻找一个接口,而不是基类(尽管可能两者都有)。

您的队列类将接受实现某种接口的对象

public class AzureTableBatchCrud
{
    public void AddQueue(IQueueableObject someItem)
    {
        /* Must ensure that the added objects are inherited on same base class */
    }
    public bool ExecuteQueue()
    {
        /* Insert or merge objects on azure table */
        return false;
    }
}

你需要定义这个接口:

interface IQueueableObject
{
    void Queue();
}

我很难理解您代码的目标。但我认为,如果你看看接口是什么,你会发现你可以用一种有用的方式来构建东西。