Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以在动态/扩展对象上创建泛型方法_C#_Generics_Dynamic - Fatal编程技术网

C# 是否可以在动态/扩展对象上创建泛型方法

C# 是否可以在动态/扩展对象上创建泛型方法,c#,generics,dynamic,C#,Generics,Dynamic,我怀疑这是不可能的,但我还没有看到一个明确的答案 我目前(正在工作)的实施情况如下 public static Main(param args[]) { dynamic Repository = GetRepository(); var query = (Repository.QueryUser() as IQueryable<User>) .Where(user => user.Name.ToLower().Contains(

我怀疑这是不可能的,但我还没有看到一个明确的答案

我目前(正在工作)的实施情况如下

public static Main(param args[])
{
    dynamic Repository = GetRepository();

    var query = (Repository.QueryUser() as IQueryable<User>)
                .Where(user => user.Name.ToLower().Contains("jack"));
}

public static dynamic GetRepository()
{
    dynamic repo = new System.Dynamic.ExpandoObject();        
    repo.QueryUser = new [] { new User() { Name = "Jack Sparrow"}}.AsQueryable<User>();
    return repo;
}
publicstaticmain(参数参数[])
{
动态存储库=GetRepository();
var query=(Repository.QueryUser()作为IQueryable)
.Where(user=>user.Name.ToLower().Contains(“jack”));
}
公共静态动态GetRepository()
{
dynamic repo=new System.dynamic.ExpandoObject();
repo.QueryUser=new[]{new User(){Name=“Jack Sparrow”}}.AsQueryable();
回购回报;
}
为了更好地用泛型方法模拟(常用的)存储库接口,我想实现如下内容:

public interface IRepository
{
    IQueryable<T> Query<T>();
}

public static Main(param args[])
{
    IRepository Repository = GetRepository();  // return a dynamic

    var query = Repository.Query<User>() 
                 .Where(user => user.Name.ToLower().Contains("jack"));
}


public static dynamic GetRepository()
{
    dynamic repo = new System.Dynamic.ExpandoObject();

    // the issue is on the following line
    repo.Query<User> = new [] {
                          new User() {
                              Name = "Jack Sparrow"
                          }
                      }.AsQueryable<User>();
    return repo;
}
公共接口IRepository
{
IQueryable查询();
}
公共静态主(参数参数[])
{
IRepository Repository=GetRepository();//返回动态
var query=Repository.query()
.Where(user=>user.Name.ToLower().Contains(“jack”));
}
公共静态动态GetRepository()
{
dynamic repo=new System.dynamic.ExpandoObject();
//问题在下面一行
repo.Query=new[]{
新用户(){
Name=“杰克·斯派洛”
}
}.AsQueryable();
回购回报;
}

是否有可能解决此问题(可能使用System.Dynamic namespace中的某些内容)?

我怀疑,您只能获取或设置
ExpandooObject的“属性”(或),而不能定义新方法。如果要这样做,您必须创建自己的动态对象,并为其添加自己的成员

但我觉得我必须这么说,为什么不干脆用构图来代替呢?创建一个类,向其中添加方法,并具有expando的属性

class MyClass
{
    public dynamic Expando { get; } = new ExpandoObject();
    public void MyMethod<T>() { }
}
有了它,您可以像使用任何expando对象一样使用它

dynamic expando = new ExtendedExpandoObject();
Console.WriteLine(expando.Value);          // the original expando
expando.Length = 12;                       // set a new property on the expando
Console.WriteLine(expando.Length);         // get a property on the expando
Console.WriteLine(expando.GetMessage());   // call the new method
Console.WriteLine(expando.GetTypeName<ExtendedExpandoObject>());  // call the generic method
Console.WriteLine(expando.Value.Length);   // get the property on the original expando
dynamic expando=新的ExtendedExpandoObject();
Console.WriteLine(expando.Value);//原版expando
expando.长度=12;//在expando上设置新属性
控制台写入线(扩展长度);//获取expando上的属性
Console.WriteLine(expando.GetMessage());//调用新方法
Console.WriteLine(expando.GetTypeName());//调用泛型方法
Console.WriteLine(expando.Value.Length);//获取原始expando上的属性
您只需要DynamicMetaObjectWrapper:

public abstract class DynamicMetaObjectWrapper : DynamicMetaObject
{
    protected DynamicMetaObjectWrapper(DynamicMetaObject metaObject)
            : base(metaObject.Expression, metaObject.Restrictions, metaObject.Value)
    {
        BaseMetaObject = metaObject;
    }
    public DynamicMetaObject BaseMetaObject { get; }

    public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg) => BaseMetaObject.BindBinaryOperation(binder, arg);
    public override DynamicMetaObject BindConvert(ConvertBinder binder) => BaseMetaObject.BindConvert(binder);
    public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args) => BaseMetaObject.BindCreateInstance(binder, args);
    public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes) => BaseMetaObject.BindDeleteIndex(binder, indexes);
    public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder) => BaseMetaObject.BindDeleteMember(binder);
    public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes) => BaseMetaObject.BindGetIndex(binder, indexes);
    public override DynamicMetaObject BindGetMember(GetMemberBinder binder) => BaseMetaObject.BindGetMember(binder);
    public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) => BaseMetaObject.BindInvoke(binder, args);
    public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) => BaseMetaObject.BindInvokeMember(binder, args);
    public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) => BaseMetaObject.BindSetIndex(binder, indexes, value);
    public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) => BaseMetaObject.BindSetMember(binder, value);
    public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder) => BaseMetaObject.BindUnaryOperation(binder);
    public override IEnumerable<string> GetDynamicMemberNames() => BaseMetaObject.GetDynamicMemberNames();
}
公共抽象类DynamicMetaObjectWrapper:DynamicMetaObject
{
受保护的DynamicMetaObjectWrapper(DynamicMetaObject元对象)
:base(metaObject.Expression、metaObject.Restrictions、metaObject.Value)
{
BaseMetaObject=元对象;
}
公共DynamicMetaObject BaseMetaObject{get;}
公共重写DynamicMetaObject BindBaryOperation(BinaryOperationBinder,DynamicMetaObject arg)=>BaseMetaObject.BindBaryOperation(binder,arg);
公共覆盖DynamicMetaObject BindConvert(ConvertBinder)=>BaseMetaObject.BindConvert(binder);
公共覆盖DynamicMetaObject BindCreateInstance(CreateInstanceBinder,DynamicMetaObject[]args)=>BaseMetObject.BindCreateInstance(binder,args);
公共覆盖DynamicMetaObject BindDeleteIndex(DeleteIndexBinder,DynamicMetaObject[]索引)=>BaseMetaObject.BindDeleteIndex(binder,索引);
公共重写DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)=>BaseMetaObject.BindDeleteMember(binder);
公共覆盖DynamicMetaObject BindGetIndex(GetIndexBinder,DynamicMetaObject[]索引)=>BaseMetObject.BindGetIndex(binder,索引);
公共重写DynamicMetaObject BindGetMember(GetMemberBinder binder)=>BaseMetaObject.BindGetMember(binder);
公共覆盖DynamicMetaObject BindInvoke(InvokeBinder binder,DynamicMetaObject[]args)=>BaseMetaObject.BindInvoke(binder,args);
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder,DynamicMetaObject[]args)=>BaseMetaObject.bindInvokeMber(binder,args);
公共覆盖DynamicMetaObject BindSetIndex(SetIndexBinder,DynamicMetaObject[]索引,DynamicMetaObject值)=>BaseMetObject.BindSetIndex(binder,索引,值);
公共覆盖DynamicMetaObject BindSetMember(SetMemberBinder,DynamicMetaObject值)=>BaseMetObject.BindSetMember(binder,值);
公共重写DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder)=>BaseMetaObject.BindUnaryOperation(binder);
公共覆盖IEnumerable GetDynamicMemberNames()=>BaseMetaObject.GetDynamicMemberNames();
}

假设的expando对象实现不“满足”接口;它没有可称为
Query()
Query()
的通用
Query
方法。它只有一个非泛型的
Query()
方法返回
IQueryable
。也就是说,
Query
似乎无论如何都不是一件合理的事情,尤其是在没有类型约束的情况下

我建议使用非泛型方法,如
QueryUsers
QueryFoos
等,或者使用
IRepository
接口指定
IQueryable Query()
方法。以下是如何使用库实现后一种方法:

using ImpromptuInterface;
using ImpromptuInterface.Dynamic;
using System.Linq;

public interface IRepository<T>
{
    IQueryable<T> Query();
}

public class User
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main(params string[] args)
    {
        IRepository<User> repo = GetUserRepository();  // dynamically construct user repository

        var query = repo.Query()
                     .Where(user => user.Name.ToLower().Contains("jack"));
    }

    public static IRepository<User> GetUserRepository()
    {
        var repo = new
        {
            Query = Return<IQueryable<User>>.Arguments(() => new[] {
                new User() {
                    Name = "Jack Sparrow"
                }
            }.AsQueryable())
        }.ActLike<IRepository<User>>();

        return repo;
    }
}
使用impromptu接口;
使用ImpromptuInterface.Dynamic;
使用System.Linq;
公共接口假定
{
IQueryable查询();
}
公共类用户
{
公共字符串名称{get;set;}
}
公共课程
{
公共静态void Main(参数字符串[]args)
{
IRepository repo=GetUserRepository();//动态构造用户存储库
var query=repo.query()
.Where(user=>user.Name.ToLower().Contains(“jack”));
}
公共静态IRepository GetUserRepository()
{
using ImpromptuInterface;
using ImpromptuInterface.Dynamic;
using System.Linq;

public interface IRepository<T>
{
    IQueryable<T> Query();
}

public class User
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main(params string[] args)
    {
        IRepository<User> repo = GetUserRepository();  // dynamically construct user repository

        var query = repo.Query()
                     .Where(user => user.Name.ToLower().Contains("jack"));
    }

    public static IRepository<User> GetUserRepository()
    {
        var repo = new
        {
            Query = Return<IQueryable<User>>.Arguments(() => new[] {
                new User() {
                    Name = "Jack Sparrow"
                }
            }.AsQueryable())
        }.ActLike<IRepository<User>>();

        return repo;
    }
}