C# 调用非泛型方法(generic<;Base>;[]参数)并传递generic<;派生>;?
调用非泛型方法并传递具有不同泛型类型的泛型参数的解决方案 我想象中的梦想:C# 调用非泛型方法(generic<;Base>;[]参数)并传递generic<;派生>;?,c#,c#-4.0,C#,C# 4.0,调用非泛型方法并传递具有不同泛型类型的泛型参数的解决方案 我想象中的梦想: void FooBulous(Foo<object>[] fooArray) { } // Accept any 'Foo<BaseType>' var fooArray = new Foo<object>[] // Array of 'Foo<BaseType>' { new Foo<Cat>(), new Foo<Dog>(),
void FooBulous(Foo<object>[] fooArray) { } // Accept any 'Foo<BaseType>'
var fooArray = new Foo<object>[] // Array of 'Foo<BaseType>'
{
new Foo<Cat>(),
new Foo<Dog>(),
};
FooBulous(fooArray); // Pass the 'Foo<BaseType>[]' array
void BarBaric(object[] barArray) { } // Can't constrain to 'Foo<>'
var barArray = new object[] // Same problem
{
new Bar<Cat>(),
new Bar<Dog>(),
};
BarBaric(barArray); // Barbaric! I thought the 'void *ptr' days were over!
void Fee(object[] params) { /* WORKS! But not constrained to 'Foo<Base>' */ }
void Fie(Foo<Cat>[] params) { /* Does not accept 'Foo<Dog>' */ }
void Foe(Foo<>[] params) { /* ERROR: 'Type expected' */ }
void Fum(Foo<object>[] params) { /* Cannot convert 'Foo<Cat>' to 'Foo<object>' */ }
void FooBulous(Foo[]fooArray){}//接受任何“Foo”
var fooArray=new Foo[]//Foo的数组
{
新Foo(),
新Foo(),
};
FooBulous(foobarray);//传递“Foo[]”数组
我的现实:
void FooBulous(Foo<object>[] fooArray) { } // Accept any 'Foo<BaseType>'
var fooArray = new Foo<object>[] // Array of 'Foo<BaseType>'
{
new Foo<Cat>(),
new Foo<Dog>(),
};
FooBulous(fooArray); // Pass the 'Foo<BaseType>[]' array
void BarBaric(object[] barArray) { } // Can't constrain to 'Foo<>'
var barArray = new object[] // Same problem
{
new Bar<Cat>(),
new Bar<Dog>(),
};
BarBaric(barArray); // Barbaric! I thought the 'void *ptr' days were over!
void Fee(object[] params) { /* WORKS! But not constrained to 'Foo<Base>' */ }
void Fie(Foo<Cat>[] params) { /* Does not accept 'Foo<Dog>' */ }
void Foe(Foo<>[] params) { /* ERROR: 'Type expected' */ }
void Fum(Foo<object>[] params) { /* Cannot convert 'Foo<Cat>' to 'Foo<object>' */ }
void BarBaric(object[]barArray){}//无法约束为'Foo'
var barArray=new object[]//同样的问题
{
新条(),
新条(),
};
野蛮的(巴拉里);//野蛮!我以为“空*空”的日子已经过去了!
总之:
void FooBulous(Foo<object>[] fooArray) { } // Accept any 'Foo<BaseType>'
var fooArray = new Foo<object>[] // Array of 'Foo<BaseType>'
{
new Foo<Cat>(),
new Foo<Dog>(),
};
FooBulous(fooArray); // Pass the 'Foo<BaseType>[]' array
void BarBaric(object[] barArray) { } // Can't constrain to 'Foo<>'
var barArray = new object[] // Same problem
{
new Bar<Cat>(),
new Bar<Dog>(),
};
BarBaric(barArray); // Barbaric! I thought the 'void *ptr' days were over!
void Fee(object[] params) { /* WORKS! But not constrained to 'Foo<Base>' */ }
void Fie(Foo<Cat>[] params) { /* Does not accept 'Foo<Dog>' */ }
void Foe(Foo<>[] params) { /* ERROR: 'Type expected' */ }
void Fum(Foo<object>[] params) { /* Cannot convert 'Foo<Cat>' to 'Foo<object>' */ }
void-Fee(object[]params){/*有效!但不限于'Foo'*/}
void Fie(Foo[]参数){/*不接受'Foo'*/}
void Foe(Foo[]params){/*错误:“应键入”*/}
void Fum(Foo[]参数){/*无法将'Foo'转换为'Foo'*/}
显然,这是不可能做到的。。。有没有干净的替代方案?问题是
Foo
不是Foo
。假设Foo
如下所示:
public class Foo<T>
{
public void Method(T input)
{
...
}
}
现在.NET 4(和C#4)中提供了通用变量,但仅适用于接口和委托,并且仅适用于那些在类型参数声明点处用out
和in
修饰的接口和委托。这对你可能有用,也可能没用
另一个选项是使Foo
派生自抽象的非泛型基类Foo
,该基类提供与T
无关的所有成员。然后你可以写:
void Foobulous(Foo[] fooArray)
...
Foobulous(new Foo[] {
new Foo<object>(),
new Foo<Cat>(),
new Foo<Dog>()
});
void Foobulous(Foo[]fooArray)
...
Foobulous(新Foo[]{
新Foo(),
新Foo(),
新富()
});
只要
Foobulous
不需要使用依赖于t
的任何方法,一切都会好的,因为它可以使用不同类型参数的Foo
值。问题是Foo
不是Foo
。假设Foo
如下所示:
public class Foo<T>
{
public void Method(T input)
{
...
}
}
现在.NET 4(和C#4)中提供了通用变量,但仅适用于接口和委托,并且仅适用于那些在类型参数声明点处用out
和in
修饰的接口和委托。这对你可能有用,也可能没用
另一个选项是使Foo
派生自抽象的非泛型基类Foo
,该基类提供与T
无关的所有成员。然后你可以写:
void Foobulous(Foo[] fooArray)
...
Foobulous(new Foo[] {
new Foo<object>(),
new Foo<Cat>(),
new Foo<Dog>()
});
void Foobulous(Foo[]fooArray)
...
Foobulous(新Foo[]{
新Foo(),
新Foo(),
新富()
});
只要
Foobulous
不需要使用依赖于t
的任何方法,这一切都会很好,因为它可以使用不同类型参数的Foo
值。确实,我可以不考虑方法调用:如果可以创建数组(如您所演示的那样),然后它可以被传递给一个方法。@Jon SkeetFoo
是一个实体框架DbSet
,它是一个DbQuery
,它是。。。对象
。所以,除非有聪明的重构,否则我只能使用object[]
。@凯文:但是数组必须有用-你可以创建一个object[]
,正如你已经看到的:)@凯文:啊。。。好的,如果你不能给它一个非泛型的基类/接口,恐怕你能做的不多:(@Jon Skeet我会研究委托的事情。实际上,我想我已经在做了——在我的方法中,Foo[]
被迭代调用XElement-ToXml(DbSet-DbSet)
将实体集转换为XML。我的方法使用反射,使用MethodInfo.MakeGenericMethod(typeof(tenty))
创建一个Func
。这是一个“委托”对吗?(我知道什么…我只是一个在休假时试图编写好代码的哑巴消防员。)传递比对象更“干净”的东西
(类型限制为DbSet
)是目标。MUCHO GRACIAS!真的,我可以不考虑方法调用:如果可以创建数组(如您所演示的),然后它可以被传递给一个方法。@Jon SkeetFoo
是一个实体框架DbSet
,它是一个DbQuery
,它是一个对象
。所以,除非有一个巧妙的重构,否则我只能使用对象
。@Kevin:但是数组必须有用-你可以创建一个对象[]
正如您已经看到的:)@Kevin:Ah…好吧,如果您不能给它一个非泛型的基类/接口,恐怕没有什么可以做的了:(@Jon Skeet我会研究委托的事情。实际上,我想我已经在做了——在我的方法中,Foo[]
被迭代调用XElement-ToXml(DbSet-DbSet)
将实体集转换为XML。我的方法使用反射,使用MethodInfo.MakeGenericMethod(typeof(tenty))
创建一个Func
。这是一个“委托”对吗?(我知道什么…我只是一个在休假时试图编写好代码的哑巴消防员。)传递比对象更“干净”的东西
(类型限制为DbSet
)是目标。非常感谢!可能有一个不干净的替代方案涉及滥用dynamic
。可能有一个不干净的替代方案涉及滥用dynamic
。