C#Expression <tdelegate>的通用约束 - 无法隐式转换Type </tdelegate>

时间:2012-07-12 12:52:53

标签: c# generics lambda expression

我已经开始使用C#Expression构造了,我对在以下情况下如何应用泛型有疑问:

考虑我有一个MyObject类型,它是许多不同类型的基类。在这个课程中,我有以下代码:

// This is a String Indexer Expression, used to define the string indexer when the object is in a collection of MyObjects
public Expression<Func<MyObject, string, bool>> StringIndexExpression { get; private set;}


// I use this method in Set StringIndexExpression and T is a subtype of MyObject
protected void DefineStringIndexer<T>(Expression<T, string, bool>> expresson) where T : MyObject
{
    StringIndexExpression = expression;
}

这就是我使用DefineStringIndexer的方式:

public class MyBusinessObject : MyObject
{

   public string Name { get; set; }

   public MyBusinessObject() 
   {
       Name = "Test";
       DefineStringIndexer<MyBusinessObject>((item, value) => item.Name == value);
   }

}

但是在DefineStringIndexer内的赋值中,我得到了编译错误:

  

无法隐式转换类型   System.Linq.Expression.Expression&LT; MyObject,string,bool&gt;至   System.Linq.Expression.Expression&lt; MyBusinessObject,string,bool&gt;&gt;

在这种情况下,我可以将Generics与C#表达式一起使用吗?我想在DefineStringIndexer中使用T,这样我就可以避免在lambda中使用MyObject。

2 个答案:

答案 0 :(得分:3)

分配不起作用,因为Func<MyBusinessObject,string,bool>类型与Func<MyObject,string,bool>不分配兼容。但是,两个仿函数的参数是兼容的,因此您可以添加一个包装器以使其工作:

protected void DefineStringIndexer<T>(Func<T,string,bool> expresson) where T : MyObject {
    StringIndexExpression = (t,s) => expression(t, s);
}

答案 1 :(得分:0)

这对你有用吗?

编辑:为约束添加<T> - 认为您需要:)

class MyObject<T>
{
    // This is a String Indexer Expression, used to define the string indexer when the object is in a collection of MyObjects 
    public Expression<Func<T, string, bool>> StringIndexExpression { get; private set;} 


    // I use this method in Set StringIndexExpression and T is a subtype of MyObject 
    protected void DefineStringIndexer<T>(Expression<T, string, bool>> expresson) 
        where T : MyObject<T> // Think you need this constraint to also have the generic param
    { 
        StringIndexExpression = expression; 
    } 
}

然后:

public class MyBusinessObject : MyObject<MyBusinessObject>
{ 

   public string Name { get; set; } 

   public MyBusinessObject()  
   { 
       Name = "Test"; 
       DefineStringIndexer<MyBusinessObject>((item, value) => item.Name == value); 
   } 

}