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

时间:2013-07-24 04:40:15

标签: c# inheritance constraints

问题的标题可能对实际情况有不同的含义 简史:

我们现有代码在azure表中执行CRUD操作。但它只能在相同的Class类型上使用InserOrMergeBatch。我需要的是一个能够添加不同类型的类的方法,只要它们具有相同的基类。 Partitionkey应该不是问题,因为它是以其他方式处理的。

所以这就是问题所在。

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

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

    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...
        }
    }
    

2 个答案:

答案 0 :(得分:0)

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

Type baseClass = childClassObject.GetType().BaseType;

答案 1 :(得分:0)

如果我正确地阅读了您的问题,那么您正在寻找Interface,而不是基类(尽管可能两者都有)。

您的队列类将采用实现某个接口的对象

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();
}

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