Tag: generics

为什么Funcs不接受超过16个参数?

由于Javascript是我最熟练的语言,因此我熟悉将函数用作第一类对象。 我原以为C#缺少这个function,但后来我听说Func和Action以及delegate ,我认为这非常棒。 例如,您可以声明一个连接两个字符串的Func ,并在它们之间放置一个空格,如下所示: Func concat = (a,b) => a + ” ” + b; 当你输入时我注意到了 Func< IntelliSense显示它有17个重载: delegate System.Func delegate System.Func delegate System.Func …snip… delegate System.Func 那让我开怀大笑。 我查看了Func的MSDN文档并再次笑了起来。 这让我尝试用17个参数声明一个Func 。 它会导致错误( Using the generic type ‘System.Func’ requires 1 type arguments )。 我同意,拥有一个接受超过16个参数的Func可能不是一个好主意。 即便如此,这似乎是Func实施的一种方式。 它需要记录17个简单的不同重载。 这是它真正需要知道的全部内容:最后一个类型参数是返回类型,并且它之前的所有类型参数都是参数类型。 那么,如果我想创建一个超过16个参数的Func ,我该怎么办? 为什么还有限制? 为什么C#不能让你用任意数量的参数声明一个Func ?

是否存在“where not derived from”的generics类型约束?

我们可以在generics类型参数上指定“派生自”约束,如下所示: class Bar where T : IFooGenerator 有没有办法指定NOT派生自? 我的用例:我有一堆可并行化的FooGenerator ,每个都有相同的并行化代码,但我们不希望它们始终是并行化的。 public class FooGenerator : IFooGenerator { public Foo GenerateFoo() { … } } 因此,我创建了一个用于并行生成Foo的通用容器类: public class ParallelFooGenerator : IFooGenerator where T : IFooGenerator { public Foo GenerateFoo() { //Call T.GenerateFoo() a bunch in parallel } } 由于我希望FooGenerator和ParallelFooGenerator可以互换,因此我制作了ParallelFooGenerator : IFooGenerator 。 但是,我显然不希望ParallelFooGenerator合法。 因此,作为一个辅助问题,如果“不是从”约束条件不可能的话,是否有更好的方法来设计它?

使用不同的兼容类型覆盖属性

我需要一个带有属性的基类,我可以使用相同的属性但不同(兼容)类型派生类。 基类可以是抽象的。 public class Base { public virtual object prop { get; set; } } public class StrBase : Base { public override string prop { get; set; } // compiler error } public class UseIt { public void use() { List l = new List(); //… } } 我尝试使用Generics,但这在使用该类时给我一个问题,因为我想在List中存储不同类型的基类。 public class BaseG { public […]

从具有指定属性的generics类列表生成HTML表

我想从几个指定的参数生成一个HTML表。 具体来说,我想传递给我的方法的两个参数是:IEnumerable列表,以及T的一些属性子集。例如,假设我有一个这个类的List: class Person { string FirstName string MiddleName string LastName } 假设该列表中有5个人。 我想通过这样的方式获得该类(或任何其他任意类)的HTML表: List people; …add people to list string HTML = GetMyTable(people, “FirstName”, “LastName”); 我确信有一种更好的方法可以指定我想要从表中生成哪些属性(或者我希望从表中排除哪些属性,这样会更好,因为我通常需要大多数或所有类的属性),但是我我不确定如何(我从未使用过reflection,但我猜这是怎么回事)。 此外,该方法应接受任何类型的类的列表。 有关如何实现这一目标的任何聪明的想法?

在没有新约束的情况下创建T的新实例

如果想要创建generics的新实例,则需要定义新约束 ,如下所示: public T SomeMethod() where T : new() { return new T(); } 是否可以使用reflection在没有新约束的情况下创建T的实例,如此(包含伪代码): public T SomeMethod() { if (T has a default constructor) { return a new instance of T; } else { return Factory.CreateNew(); } }

将对象转换为通用接口

我有以下界面: internal interface IRelativeTo where T : IObject { T getRelativeTo(); void setRelativeTo(T relativeTo); } 和一堆(应该)实现它的类,例如: public class AdminRateShift : IObject, IRelativeTo { AdminRateShift getRelativeTo(); void setRelativeTo(AdminRateShift shift); } 我意识到这三个不一样: IRelativeTo IRelativeTo IRelativeTo 但是,我需要一种方法来处理所有不同的类,如AdminRateShift(和FXRateShift,DetRateShift),它们都应该实现IRelativeTo。 假设我有一个函数将AdminRateShift作为Object返回: IRelativeTo = getObjectThatImplementsRelativeTo(); // returns Object 通过对接口进行编程,我可以做我需要的,但我实际上无法将对象转换为IRelativeTo,所以我可以使用它。 这是一个微不足道的例子,但我希望它能澄清我想要做的事情。

什么时候适合使用generics与inheritance?

使用generics而不是inheritance的情况及其相关的好处,反之亦然,它们应该如何最好地结合起来? 谢谢你的回答。 我将尽力说明这个问题的动机:我有一个如下所示的课程: class InformationReturn where T : Info { InformationReturn(Employee employee, List) { … } } 现在假设我有一个带有InformationReturn参数的存储库,它必须根据Info对象T的类型在数据库中编写不同的字段。 为T类型创建不同的存储库是否更好; 一个使用reflection来确定类型的存储库; 或者是否有更好的方法在generics上使用inheritancefunction? 注意 :其他客户端代码也必须根据T的类型进行不同的操作。

如何将`where T:U`generics类型参数约束从C#转换为F#?

F#给我带来了类型推理规则的一些麻烦。 我正在编写一个简单的计算构建器,但无法正确获取我的generics类型变量约束。 我想要的代码在C#中如下所示: class FinallyBuilder { readonly Action finallyAction; public FinallyBuilder(Action finallyAction) { this.finallyAction = finallyAction; } public TB Bind(TA x, Func cont) where TA : TZ { // ^^^^^^^^^^^^^ try // this is what gives me a headache { // in the F# version return cont(x); } finally { finallyAction(x); } } } 到目前为止,我为F#版本提出的最佳(但非编译代码)是: […]

为什么不能推断嵌套generics类型?

鉴于以下课程…… public abstract class FooBase where TBar : BarBase{} public abstract class BarBase{} public class Bar1 : BarBase{} public class Foo1 : FooBase {} ……以及以下方法…… public TBar DoSomething(TFoo theFoo) where TFoo : FooBase where TBar : BarBase { return default(TBar); } 为什么下面的代码行不能表示返回类型? Bar1 myBar = DoSomething(new Foo1()); 相反,我必须指定像这样的generics类型…… Bar1 myBar = DoSomething(new Foo1());

具有自引用类型约束的generics类

请考虑以下代码: abstract class Foo where T : Foo, new() { void Test() { if(Bar != null) Bar(this); } public event Bar Bar; } delegate void Bar(T foo) where T : Foo, new(); 行Bar(this)导致以下编译器错误: 参数类型为Foo 的参数类型不可分配 T被约束为Foo ,因为我希望派生类基本上告诉基类它们的类型,以便可以在事件回调中使用该类型,以便保存实现者不必将回调参数强制转换为派生类型。 我可以看到代码不能正常工作,但我对如何正确执行此操作有一点障碍,而不会使用可用于任何旧事物的generics委托。 我也不太确定为什么T约束不会产生编译器错误,因为它似乎是递归的。 编辑 我想要澄清这一点! 这是一个新的例子,我希望会更清楚。 请注意,下面的OnDuckReady事件处理程序会生成编译器错误。 如何让事件以正确的类型传递? abstract class Animal where T : Animal, new() { void Test() […]