代码之家  ›  专栏  ›  技术社区  ›  Gup3rSuR4c

在一般提供者中如何查找和编辑T的属性?(C#)

  •  2
  • Gup3rSuR4c  · 技术社区  · 13 年前

    因此,我正在为我的存储库实现创建一个通用的提供者,我的BaseController(ASP.NET MVC 2)将使用它来实现低级对象。这些对象具有常见的操作,例如激活/停用/删除/编辑,因此我将始终对每个对象使用相同的属性。问题是,因为我不知道t是什么,我显然无法访问它的属性。

    所以,我的问题是,有人能告诉我如何从物体中得到我需要的属性吗。我见过一些人谈论反射,另一些人谈论表达树,我都不知道如何使用。

    我确实有一个通用的存储库,我相信它使用了表达式树(从某个网站上复制的),但是我不知道我在用它做什么。。。如果有帮助的话,以下是我目前所掌握的情况:

    public class Provider<T> where T : class {
        private readonly Repository<T> Repository = null;
    
        public Provider(
            Repository<T> Repository) {
            this.Repository = Repository;
        }
    
        public void Activate(
            int Id) {
            T Entity = this.Repository.Select(Id);
    
            // Need to get the property here, change it and move on...
    
            this.Repository.Submit();
        }
    }
    

    我很感激你在这方面的帮助。

    3 回复  |  直到 13 年前
        1
  •  4
  •   Anthony Pegram    13 年前

    如果这些类有公共操作,听起来它们应该继承自同一个基类或实现同一个接口,对吗?如果是,则使用该接口/基作为T的约束

    public class Provider<T> where T : ICommonInterface
    

    然后您将拥有对接口或基类提供的共享成员的编译时访问权。

        2
  •  0
  •   CRice    13 年前

    你可以采取行动

    public void Activate(int Id, Action<T> doSomething)
    {
        T Entity = this._repository.Select(Id);
        // Need to get the property here, change it and move on... 
        doSomething(Entity);
        _repository.Submit();
    }
    

    然后使用Action委托(在本例中通过lambda),当调用activate时将知道属性:

    prov.Activate(5, x => x.Address = "fgfgf");
    
        3
  •  0
  •   sheikhjabootie    13 年前

    最好的解决方案是给对象一个公共的基类型,并将类型参数T约束为该类型。然后,您可以在编译时访问公共基类型的方法或属性:

    public class Provider<T> where T : ICommon 
    { 
        ...
    }
    

    public class Provider<T> where T : CommonBase
    {
        ...
    }
    

    如果这是不可能的,那么如果没有公共基类型,您所能做的就是反射要查找和调用您感兴趣的属性的对象:

    public void Activate(int Id) 
    { 
        T entity = this.Repository.Select(Id); 
    
        // Interrogate the type of the entity and get the property called "MyPropertyName"
        PropertyInfo pi = entity.GetType().GetProperty("MyPropertyName"); 
    
        // Invoke the property against the entity instance - this retrieves the 
        // value of the property.
        var value = (YourType)(pi.GetValue(entity, null));
    
        // Do somethign with the value...        
    
        this.Repository.Submit(); 
    } 
    

    我要补充的是,反射比较昂贵,而且您也会丢失编译时验证。但在这种情况下很方便。

    您可以通过调用以下命令获取用于处理方法的MethodInfo对象:

    MethodInfo mi = entity.GetType().GetMethod("MyMethodName");