gpt4 book ai didi

c# - 使用泛型类型和表达式的扩展方法选择

转载 作者:太空狗 更新时间:2023-10-29 21:45:03 25 4
gpt4 key购买 nike

我有一些扩展方法使用 Expression 参数来拉入属性成员并对其进行操作,并且我有一个针对成员是 IEnumerable< 的特定情况的重载>。但是,当从泛型类内部调用时,它似乎不符合预期的方法重载(对于下面的 r4)。在类之外选择了正确的方法。

这是怎么回事?这会奏效还是我需要找到一种新方法?

(这是在 C# 5 中)

public class Test
{
public void MyTest()
{
// returns "Object"
var r1 = new MyClass<object>().Ext(a => a.Content);

// returns "Enumerable"
var r2 = new MyClass<IEnumerable<object>>().Ext(a => a.Content);

// returns "Object"
var r3 = new MyClass<object>().TestExt();

// returns "Object" (I was expecting "Enumerable")
var r4 = new MyClass<IEnumerable<object>>().TestExt();

// returns "Enumerable"
var r5 = new MyClass<int>().TestExt2();
}
}

public class MyClass<T>
{
public T Content { get; set; }

public IEnumerable<object> OtherContent { get; set; }

public string TestExt()
{
return this.Ext(a => a.Content);
}

public string TestExt2()
{
return this.Ext(a => a.OtherContent);
}
}

public static class MyExtensions
{
public static string Ext<T>(this T obj, Expression<Func<T, IEnumerable<object>>> memberExpression)
{
return "Enumerable";
}

public static string Ext<T>(this T obj, Expression<Func<T, object>> memberExpression)
{
return "Object";
}
}

最佳答案

泛型不是动态类型。要调用的重载在编译时被卡住。当程序稍后运行时,即使变量碰巧持有更具体的运行时类型,也没关系,因为重载已在编译时修复。

你的方法:

public string TestExt()
{
return this.Ext(a => a.Content);
}

必须在编译时绑定(bind)到 Ext 的一个特定重载.由于我们对 T 的了解(a.Content 的类型)在类 MyClass<T> 中是它可以转换为 object , 实际上只有一个重载可供选择,所以这对编译器来说很容易。

从那时起,TestExt方法体被硬编码为调用 Ext 的特定重载.


编辑:这是一个更简单的例子:

static void Main()
{
IEnumerable<object> e = new List<object>();
var r = Generic(e);
}

static string Generic<T>(T x)
{
return Overloaded(x);
}

static string Overloaded(IEnumerable<object> x)
{
return "Enumerable";
}
static string Overloaded(object x)
{
return "Object";
}

正如你现在所了解的,r变成 "Object" .

(如果您以某种方式限制了 T,例如 where T : IEnumerable<object>,情况就会有所不同)。

这对于运营商也是一样的。例如 ==运算符在某种意义上是重载的,它以一种方式用于一般引用类型,以另一种方式用于字符串。所以在下面的例子中,运算符 ==担任Overloaded的角色从之前:

static void Main()
{
string str1 = "abc";
string str2 = "a";
str2 += "bc"; // makes sure this is a new instance of "abc"

bool b1 = str1 == str2; // true
bool b2 = Generic(str1, str2); // false
}

static bool Generic<T>(T x, T y) where T : class
{
return x == y;
}

哪里b2变成 false .

关于c# - 使用泛型类型和表达式的扩展方法选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18586934/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com