我可能缺少一些非常基本的東西,但我不明白爲什麼我得到一個編碼錯誤與某些代碼,我不明白它在一個幾乎相同的代碼。編譯錯誤與泛型類型T傳遞給一個函數兩次
因此,我來到這裏的錯誤:
//parent.GetChildren() returns a IEnumerable<IBase>
F1<T>(T parent, Func<string, T, string> func) where T: IBase
{
F1(parent.GetChildren(), func);
//This would wok instead:
//F1(parent.GetChildren().Select(c=> (T)c), func);
}
F1<T>(IEnumerable<T> children, Func<string, T, string> func) where T: IBase
{
...
}
,但我不會在這裏動手:
//parent.GetChildren() returns a IEnumerable<IBase>
F1<T>(T parent, Func<string, string, string> func) where T: IBase
{
//Works, no casting required
F1(parent.GetChildren(), func);
}
F1<T>(IEnumerable<T> children, Func<string, string, string> func) where T: IBase
{
...
}
基本上,如果我用的是普通的T型中傳遞的參數的功能之一,其參數我收到以下編譯錯誤:
錯誤1:「ConsoleApplication1.Program.FooConsumer.Consume1<ConsoleApplication1.Program.IBase>(System.Collections.Generic.IEnumerable<ConsoleApplication1.Program.IBase>, string, System.Func<string,ConsoleApplication1.Program.IBase,string>)
」的最佳重載方法匹配有一些無效參數
錯誤2:參數「3」:無法從「System.Func<string,T,string>
」轉換爲「System.Func<string,ConsoleApplication1.Program.IBase,string>
」
以下是完整的示例代碼,請參見注釋代碼(去掉註釋來獲得編譯錯誤):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
interface IBase
{
string GetName();
IEnumerable<IBase> GetChildren();
}
class Foo : IBase
{
private string _Name;
public Foo(string name)
{
_Name = name;
}
public string GetName()
{
return _Name;
}
public IEnumerable<IBase> GetChildren()
{
var r = new List<IBase>();
r.Add(new Foo("foo 1"));
r.Add(new Foo("foo 2"));
return r;
}
}
class FooConsumer
{
public string Consume1<T>(IEnumerable<T> objects, string template, Func<string, T, string> func) where T : IBase
{
var s = "";
foreach (var o in objects)
{
s += func(template, o);
}
return s;
}
public string Consume2<T>(IEnumerable<T> objects, string template, Func<string, string, string> func) where T : IBase
{
var s = "";
foreach (var o in objects)
{
s += func(template, o.GetName()) + "\n";
}
return s;
}
//Here if I don't cast each child as a T I get an error
public string Consume1<T>(T parent_object, string template, Func<string, T, string> func) where T : IBase
{
// return this.Consume1(parent_object.GetChildren(), template, func); //<-- UNCOMMENTING THIS WOULD NOT COMPILE
return this.Consume1(parent_object.GetChildren().Select(c => (T)c), template, func);
}
//Here I would expect it to behave identically, but instead I don't get an Error and code compiles fine.
//How can the last parameter be affecting the first parameter?!
public string Consume2<T>(T parent_object, string template, Func<string, string, string> func) where T : IBase
{
return this.Consume2(parent_object.GetChildren(), template, func); //<-- THIS CALL DOES NOT DO THE CAST BUT COMPILES JUST FINE!!!
}
}
static void Main(string[] args)
{
FooConsumer fc = new FooConsumer();
Foo f = new Foo("parent");
Func<string, IBase, string> func1 = (template, node) =>
string.Format(template, node.GetName());
Func<string, string, string> func2 = (template, name) =>
string.Format(template, name);
string s1 = fc.Consume1(f, "<li>{0}</li>", func1);
string s2 = fc.Consume2(f, "<li>{0}</li>", func2);
Console.WriteLine("Executing first:");
Console.WriteLine(s1);
Console.WriteLine("Executing second:");
Console.WriteLine(s2);
}
}
}
非常感謝,
朱塞佩
+1很好的解釋。 – 2009-09-09 14:16:18
謝謝,我明白,但爲什麼消費2沒有任何鑄造工作? – 2009-09-09 14:32:26