我有一个重载的泛型方法,用于获取类型为PageData
的对象的属性值。属性集合实现为Dictionary<string, object>
。该方法用于避免繁琐检查属性是否为null
并且具有值。
一种常见的模式是将PageData
的集合绑定到转发器。然后在转发器中,每个PageData
都是Container.DataItem
,类型为object
。
我针对PageData写了原始的扩展方法:
public static T GetPropertyValue<T>(this PageData page, string propertyName);
但是在绑定数据时,您必须将Container.DataItem
转换为PageData
:
<%# ((PageData)Container.DataItem).GetPropertyValue("SomeProperty") %>
我有点痒,想知道我是否无法重载方法来扩展对象,将此方法放在一个单独的命名空间中(以免污染继承object
的所有内容)并仅使用此命名空间我的aspx / ascx文件,我知道我已经数据绑定了PageData
的集合。有了这个,我就可以避免在我的aspx / ascx中乱码,例如
// The new overload
public static T GetPropertyValue<T>(this object page, string propertyName);
// and the new usage
<%# Container.DataItem.GetPropertyValue("SomeProperty") %>
在object
版本的GetPropertyValue
内,我将page
参数转换为PageData
public static T GetPropertyValue<T>(this object page, string propertyName)
{
PageData data = page as PageData;
if (data != null)
{
return data.GetPropertyValue<T>(propertyName);
}
else
{
return default(T);
}
}
然后将调用转发到PageData
GetPropertyValue
版本的StackOverflowException
,但是,我正在获得object
,因为它只是重新调用{{ 1}}版本。
如何让编译器意识到PageData
重载比object
重载更好?
答案 0 :(得分:2)
扩展方法语法只是在对象上调用静态方法的语法糖。只需像调用任何其他常规静态方法一样调用它(如果需要,可以抛出参数)。
即,
public static T GetPropertyValue<T>(this object page, string propertyName)
{
PageData data = page as PageData;
if (data != null)
{
//will call the GetPropertyValue<T>(PageData,string) overload
return GetPropertyValue<T>(data, propertyName);
}
else
{
return default(T);
}
}
根据您的评论,我编写了一个测试程序来查看此行为。看起来它确实采用了最本地化的方法。
using System;
using Test.Nested;
namespace Test
{
namespace Nested
{
public static class Helper
{
public static void Method(this int num)
{
Console.WriteLine("Called method : Test.Nested.Helper.Method(int)");
}
}
}
static class Helper
{
public static void Method(this object obj)
{
Console.WriteLine("Called method : Test.Helper.Method(object)");
}
}
class Program
{
static void Main(string[] args)
{
int x = 0;
x.Method(); //calls the object overload
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Console.WriteLine();
}
}
}
为确保嵌套不会影响任何内容,请尝试删除对象重载:
using System;
using Test.Nested;
namespace Test
{
namespace Nested
{
public static class Helper
{
public static void Method(this int num)
{
Console.WriteLine("Called method : Test.Nested.Helper.Method(int)");
}
}
}
static class Helper
{
public static void Method(this string str)
{
Console.WriteLine("Called method : Test.Helper.Method(string)");
}
}
class Program
{
static void Main(string[] args)
{
int x = 0;
x.Method(); //calls the int overload
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Console.WriteLine();
}
}
}
果然,调用了int
重载。
所以我认为只是在使用扩展方法语法时,编译器首先在当前命名空间中查找适当的方法(“最本地”),然后查找其他可见的命名空间。
答案 1 :(得分:1)
它应该已经正常工作了。我在下面列出了一个简短但完整的例子。我建议您仔细检查您的方法签名和电话,如果您仍然遇到问题,请尝试提出一个类似的简短但完整的程序来编辑您的问题。我怀疑你会在提出这个程序时找到答案,但至少如果你不这样做,我们应该能够重现它并修复它。
using System;
static class Extensions
{
public static void Foo<T>(this string x)
{
Console.WriteLine("Foo<{0}>(string)", typeof(T).Name);
}
public static void Foo<T>(this object x)
{
Console.WriteLine("Foo<{0}>(object)", typeof(T).Name);
string y = (string) x;
y.Foo<T>();
}
}
class Test
{
static void Main()
{
object s = "test";
s.Foo<int>();
}
}