5

मैं एक आधार अमूर्त वर्ग और उसके सार प्रकार पैरामीटर है के रूप में:हैंडलिंग कक्षाएं सार वर्ग और प्रकार पैरामीटर से निहित

public abstract class Database<T> where T : DatabaseItem, new() { 
    protected List<T> _items = new List<T>(); 
    protected virtual void Read (string[] cols) { 
    T item = new T(); 
    ... 
} 

public abstract class DatabaseItem { 
    ... 
} 

तो मैं इसे से निहित बच्चों वर्गों की संख्या है:

public class ShopDatabase : Database<ShopItem> {} 
public class ShopItem : DatabaseItem {} 

public class WeaponDatabase : Database<WeaponItem> {} 
public class WeaponItem : DatabaseItem {} 

... 

अब, मैं डेटाबेस को ट्रैक रखने के लिए शब्दकोश डालना चाहता हूं और डेटाबेस इटैम प्रकार का उपयोग करके उन्हें वापस करने के लिए एक विधि,

Dictionary<Type, Database<DatabaseItem>> databases; 

public static Database<T> GetDatabase<T>() where T: DatabaseItem { 
    return databasebases [typeof (T)]; 
} 

तो यह दिया मुझे क्योंकि DatabaseItem सार है त्रुटि " 'टी' एक सार्वजनिक parameterless निर्माता के साथ एक गैर सार प्रकार है ताकि इसे पैरामीटर के रूप में 'टी' का उपयोग करने में होना चाहिए"। मैं DatabaseItem गैर सार प्रकार के रूप में किया जाता है, त्रुटि चला गया है, लेकिन अभी भी प्रकार रूपांतरण त्रुटियों के बहुत बाहर आ गया ...

मिले एक समान question लेकिन मैं अभी भी समझ में नहीं आता ...

क्या बेहतर है समाधान प्राप्त करने के लिए समाधान/संरचना?

+0

शायद अपने डाटाबेस वर्ग के लिए एक इंटरफेस, जैसे शब्दकोश परिभाषित करने के लिए <प्रकार, IDatabase> –

उत्तर

3

सरलतम आप कर सकते हैं वस्तुओं के रूप में Database<T> वंश स्टोर करने के लिए है: एक गैर सामान्य प्रकार या डेटाबेस के लिए inerface परिभाषित करें, तो इस कोड का उपयोग पैरामीटर रहित कन्स्ट्रक्टर के साथ सार वर्ग, यह या तो मदद नहीं करेगा, क्योंकि typeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)

नोट, GetDatabase<T> विधि के लिए सामान्य बाधा Database<T> कक्षा के समान होना चाहिए।

अपडेट करें।

यह जानने का कोई तरीका है कि कक्षा का किस प्रकार का पैरामीटर उपयोग कर रहा है? जैसे शॉपडाबेस देना, मैं ShopItem प्राप्त करना चाहता हूं। मैं इसे की जरूरत है जब मैं डेटाबेस शब्दकोश प्रतिबिंब

उपयोग प्रारंभ:

var databaseItemType = typeof(ShopDatabase).BaseType.GetGenericArguments()[0]; 
इस तरह के मामलों के लिए

:

class FooDatabase : Database<FooItem> {} 
class BooDatabase : FooDatabase {} 
// etc... 

आप Database<FooItem> खोजने के लिए विरासत पेड़ के माध्यम से लूप की आवश्यकता होगी।

+0

मैं हम लगभग वहाँ लगता है, वहाँ एक रास्ता एक वर्ग का उपयोग कर किस प्रकार पैरामीटर पता करने के लिए है? उदा। ShopDatabase देकर, मैं ShopItem प्राप्त करना चाहता हूं। मुझे इसकी आवश्यकता है जब मैं * डेटाबेस * शब्दकोश –

+0

@RichardFu प्रारंभ करता हूं: मैंने जवाब अपडेट किया है। – Dennis

1

बुरी खबर यह है कि आप बिना किसी प्रकार के कलाकार के अपने कोड का उपयोग नहीं कर सकते हैं। यहां तक ​​कि अगर आप गैर करने के लिए DatabaseItem बारी

static class DatabaseManager 
{ 
    private static Dictionary<Type, object> databases = new Dictionary<Type, object>(); 

    // .... 

    public static Database<T> GetDatabase<T>() 
     where T : DatabaseItem, new() 
    { 
     return (Database<T>)databases[typeof(T)]; 
    } 
} 

:

Dictionary<Type, Database> databases; 
public static Database<T> GetDatabase<T>() where T: DatabaseItem, new() 
{ 
    return databasebases[typeof(T)] as Database<T>; 
} 
संबंधित मुद्दे