获取C#类中属性的确切类型

问题描述:

对于总体标题很抱歉,但用几句话解释我的问题目前有点困难。获取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

您的工厂方法不应该是静态的吗?发布您的实际代码。 –

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

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

您可以通过您的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}; 
} 

这种结构是一个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;