2014-02-28 34 views
1

對於總體標題很抱歉,但用幾句話解釋我的問題目前有點困難。獲取C#類中屬性的確切類型

所以我有一個簡單的類工廠是這樣的:

public Model Construct<T>(T param) where T : IModelable 
    { 
     new Model {Resource = param}; 
     return n; 
    } 

Model類看起來是這樣的:

public class Model 
{ 
    public object Resource { get; set; } 
} 

的問題是,你可以看到,是資源,目前的目的。我希望那個資源應該是類型,從構造中得到什麼,不會丟失類型安全的...

我試圖用類型參數解決它,但它失敗了,因爲我可以擴展Model類類型參數,但是如果我想將它存儲到一個簡單的類庫中呢?

然後構造會的工作,但如果我想從儲備庫中獲得實例化類,我不得不再次聲明類型放慢參數,如:

Repository.Get<Model<Spaceship>>(0) ....當然是因爲我是錯的就像Model自己知道的那樣,在Construct中添加了什麼類型的資源。

有沒有人知道如何處理這個問題?

整個代碼目前是這樣的:

/// <summary> 
///  Class Repository 
/// </summary> 
public sealed class Repository 
{ 
    /// <summary> 
    ///  The _lock 
    /// </summary> 
    private static readonly object _lock = new object(); 

    /// <summary> 
    ///  The _syncroot 
    /// </summary> 
    private static readonly object _syncroot = new object(); 

    /// <summary> 
    ///  The _instance 
    /// </summary> 
    private static volatile Repository _instance; 

    /// <summary> 
    ///  The _dict 
    /// </summary> 
    private static readonly Dictionary<int, object> _dict 
     = new Dictionary<int, object>(); 


    /// <summary> 
    ///  Prevents a default data of the <see cref="Repository" /> class from being created. 
    /// </summary> 
    private Repository() 
    { 
    } 

    /// <summary> 
    ///  Gets the items. 
    /// </summary> 
    /// <value>The items.</value> 
    public static Repository Data 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       lock (_lock) 
       { 
        if (_instance == null) _instance = new Repository(); 
       } 
      } 
      return _instance; 
     } 
    } 

    /// <summary> 
    ///  Allocates the specified id. 
    /// </summary> 
    /// <param name="id">The id.</param> 
    /// <param name="parameter">The parameter.</param> 
    /// <resource name="id">The id.</resource> 
    /// <resource name="parameter">The parameter.</resource> 
    public void Allocate(int id, object parameter) 
    { 
     lock (_syncroot) 
     { 
      _dict.Add(id, parameter); 
     } 
    } 

    /// <summary> 
    ///  Gets the specified id. 
    /// </summary> 
    /// <typeparam name="T">The type of the tref.</typeparam> 
    /// <param name="id">The id.</param> 
    /// <returns>``0.</returns> 
    /// <resource name="id">The id.</resource> 
    public T Get<T>(int id) 
    { 
     lock (_syncroot) 
     { 
      return (T) _dict[id]; 
     } 
    } 
} 

/// <summary> 
///  Class IModelFactory 
/// </summary> 
public sealed class ModelFactory 
{ 
    /// <summary> 
    ///  The _lock 
    /// </summary> 
    private static readonly object _lock = new object(); 

    /// <summary> 
    ///  The _instance 
    /// </summary> 
    private static volatile ModelFactory _instance; 

    /// <summary> 
    ///  Prevents a default instance of the <see cref="ModelFactory" /> class from being created. 
    /// </summary> 
    private ModelFactory() 
    { 
    } 

    /// <summary> 
    ///  Gets the data. 
    /// </summary> 
    /// <value>The data.</value> 
    public static ModelFactory Data 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       lock (_lock) 
       { 
        if (_instance == null) _instance = new ModelFactory(); 
       } 
      } 
      return _instance; 
     } 
    } 

    /// <summary> 
    ///  Constructs the specified param. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="param">The param.</param> 
    /// <returns>Model{``0}.</returns> 
    public Model Construct<T>(T param) where T : IModelable 
    { 
     var n = new Model {Resource = param}; 
     return n; 
    } 
} 

/// <summary> 
///  Class Model 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class Model 
{ 
    public object Resource { get; set; } 
} 

/// <summary> 
///  Interface IModelable 
/// </summary> 
public interface IModelable 
{ 
    /// <summary> 
    ///  Gets or sets the mass. 
    /// </summary> 
    /// <value>The mass.</value> 
    float Mass { get; set; } 
} 

/// <summary> 
///  Class spaceship 
/// </summary> 
public class Spaceship : IModelable 
{ 
    /// <summary> 
    ///  Gets or sets the mass. 
    /// </summary> 
    /// <value>The mass.</value> 
    public float Mass { get; set; } 
} 

所以這個問題將在這裏點燃:

添加到存儲庫:

Repository.Data.Allocate(1, ModelFactory.Data.Construct(new Spaceship())); 

沒事的,但經過:

var test_variable = Repository.Data.Get<Model>(1); 

所以現在我有一個類型參數的非類型安全對象,我不知道,c模型構造中存儲了哪種類型的類。

我使用類型放慢參數的模型類,以及的建議非常感謝,但比它會想出另外一個問題,因爲我必須要改變它的Get函數:

var test_variable = Repository.Data.Get<Model<Spaceship>>(1); 

但是這絕對是錯誤的,因爲我不知道模型中存儲了哪種類型的類,所以我希望在我希望從實例中加載實例時避免此類型參數定義存儲庫。

+1

您正在創建一個'Model'實例,但您沒有將它分配給任何東西。您確定提供了正確的代碼嗎? –

+1

你的意思是在Model類中資源應該是T? – n8wrl

+0

您的工廠方法不應該是靜態的嗎?發佈您的實際代碼。 –

回答

1

你可能需要在模型類中的泛型類型:

public class Model<T> 
{ 
    public T Resource { get; set; } 
} 
4

您可以通過您的Model類的通用解決這個問題,就像這樣:

public class Model<T> 
{ 
    public T Resource { get; set; } 
} 

然後,你Construct方法可以工作像這樣:

public Model<T> Construct<T>(T param) where T : IModelable<T> 
{ 
    return new Model<T>() {Resource = param}; 
} 
0

這種結構是一個appr oach你可以採取:

public Model<T> Construct<T>(T param) where T : IModelable 
{ 
    var n = new Model<T> {Resource = param}; 
    return n; 
} 
public class Model<T> : IModel<T> where T : IModelable 
{ 
    public T Resource { get; set; } 
} 
public interface IModel<out T> where T : IModelable 
{ 
    T Resource { get; } 
} 

covariant interface允許你指的是類型更一般地,你想,在那你可以傳遞一個IEnumerable<string>弄成期待的IEnumerable<object>以同樣的方式。

IModel<Spaceship> shipModel = // whatever 
IModel<IModelable> model = shipModel; 
//or even: 
List<Model<Spaceship>> shipModels = // whatever 
IEnumerable<IModel<IModelable>> models = shipModels;