标签: generic-constraints

Delphi XE:我是否可以使用classtype约束泛型类型的参数调用虚拟构造函数而不必重新签名?

我正在尝试为复合控件构建一个通用的祖先.最初的想法看起来像这样:

type
  TCompositeControl<TControl1: TControl; TControl2: TControl> = class(TWinControl)
  private
    FControl1,
    FControl2: TControl;
  public
    constructor Create(AOwner: TComponent); override; 
  end;

  TLabelAndEdit = TCompositeControl<TLabel, TEdit>; // simple example for illustration only

constructor TCompositeControl<TControl1,TControl2>.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FControl1 := TControl1.Create(Self);
  FControl2 := TControl2.Create(Self);
end;
Run Code Online (Sandbox Code Playgroud)

您可能已经知道,这将触发编译器错误E2568:无法在类型参数声明中创建没有CONSTRUCTOR约束的新实例.constructor然而,添加约束并没有帮助,因为它意味着无参数构造函数.

转换模板以TControl使代码可编译:

...
FControl1 := TControl(TControl1).Create(Self);
...
Run Code Online (Sandbox Code Playgroud)

...但它会在运行时导致访问冲突.

一个可能有用的黑客是通过RTTI调用构造函数,但我认为这是一个相当脏的解决方案.

另一个基本上有效的黑客是使用类类型变量作为中间体:

type
  TControlClass = class of TControl;

constructor TCompositeControl<TControl1,TControl2>.Create(AOwner: TComponent);
var
  lCtrlClass1,
  lCtrlClass2: TControlClass;
begin
  inherited Create(AOwner);
  lCtrlClass1 := TControl1;
  FControl1 := lCtrlClass1.Create(Self);
  lCtrlClass2 := TControl2; …
Run Code Online (Sandbox Code Playgroud)

delphi generics polymorphism constructor generic-constraints

5
推荐指数
1
解决办法
1096
查看次数

C#无界泛型类型作为约束

是否可以使用通用约束,这是一种无界泛型类型?

例如:

public T DoSomething<T>(T dictionary) where T : IDictionary<,>
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

编辑:为了解释上下文,我想将方法​​的用法限制为IDictionary,但对于方法本身而言,TKey和TValue究竟是什么并不重要.

c# generics generic-constraints

5
推荐指数
1
解决办法
844
查看次数

如何在 C# 中通过反射提取泛型方法约束?

给定一个类型的对象,System.Reflection.MethodInfo如何提取通用参数约束?不知怎的,我找不到有关此的合理信息。

c# generics reflection generic-constraints

5
推荐指数
1
解决办法
1198
查看次数

TypeScript“扩展”通用约束

extends在 TypeScript 中使用约束,如下所示:

class Animal {}
class Lion extends Animal {}
class Bear extends Animal {}

class ZooKeeper<T extends Animal> {
    constructor(p: T = new Animal()) {

    }
}

new ZooKeeper(new Animal());
Run Code Online (Sandbox Code Playgroud)

p: T = new Animal()包含一个错误:

“动物”类型不能分配给“T”类型。

构造函数 Animal(): 动物

为什么,我该怎么做,以便我可以使用Animal, 代替Animal子类型?

来源

generics generic-constraints typescript

5
推荐指数
1
解决办法
3480
查看次数

Swift 泛型:将类型参数约束到协议

如何指定泛型类型参数只能是协议(或符合该协议的协议),而不能是符合该协议的类?

例如:

import Foundation

@objc protocol MyProtocol {
    var name: String { get }
}

@objc protocol MySubProtocol: MyProtocol {
    func foo()
}

class MyImplementation: MySubProtocol {
    var name: String

    init(name: String) {
        self.name = name
    }

    func foo() {
        print("Foo! Name: \(self.name)")
    }
}

class InterfaceMaker<T: MyProtocol> {
    init() {}

    func makeInterface() -> NSXPCInterface {
        return NSXPCInterface(with: T.self) // Cannot convert value of type 'T.Type' to expected argument type 'Protocol'
    }


    func getProxy() -> T? {
        // Some magic …
Run Code Online (Sandbox Code Playgroud)

generics type-parameter generic-constraints swift

5
推荐指数
1
解决办法
1314
查看次数

需要帮助来理解这个C#泛型类

我正在学习Nhibernate 3.0.在其中一个示例代码示例中,它创建了一个抽象基类实体类:

public abstract class Entity<T> where T : Entity<T>
Run Code Online (Sandbox Code Playgroud)

然后,使Customer实体继承自基Entity类:

public class Customer : Entity<Customer>
Run Code Online (Sandbox Code Playgroud)

我知道这是一个抽象的通用类,它是使用where关键词,以确保类型TEntity<T>,这是我感到困惑.

Customer继承自" Entity<Customer>",这个" Entity<Customer>"取" Customer" T,但这Customer不是" Entity<T>".

请帮助我理解这一点,我真的很困惑这个泛型类.

c# generics nhibernate generic-constraints

4
推荐指数
1
解决办法
225
查看次数

泛型类型相互引用

我编写了简单的解析器并希望实现接下来的两个接口:

public interface IResult<TValue, TToken> 
    where TToken : ITokenizer<IResult<TValue, TToken>, TValue>
{
    TToken Tokenizer { get; }
    TValue Value { get; }
}

public interface ITokenizer<TResult, TValue> 
    where TResult : IResult<TValue, ITokenizer<TResult, TValue>>
{
    TResult Advance();
}
Run Code Online (Sandbox Code Playgroud)

它还有下一个用途:ITokenizer是一个不可变的类,用于按标记拆分字符串。我们可以调用Advance方法并获取Result:下一个标记和下一个标记器。所以,我想在Result类中存储令牌和标记器,并希望为此添加编译时约束。

现在我在构建这两个接口期间出现编译时错误。

我认为下一个类可以实现具有所有约束的接口:

public class Result : IResult<string, Tokenizer>
{ /* implement interface */}

public class Tokenizer : ITokenizer<Result, string>
{ /* implement interface */}
Run Code Online (Sandbox Code Playgroud)

谁能解释一下出了什么问题?也许为什么这是不可能的,或者如何使此代码正确?

PS 对于我的任务,我可以简单地使用IResult<TValue, TToken>没有任何约束的接口,但是我可以在不丢失约束的情况下实现它吗?

编译器错误:

(3:22) The type …
Run Code Online (Sandbox Code Playgroud)

c# generics generic-constraints

4
推荐指数
1
解决办法
752
查看次数

在 C# 中,如何将泛型类型参数约束为仅接受可为 null 的值类型?

where T : struct约束仅允许将可接受类型参数的域限制为一组值类型(与包括值和引用类型的类型的超集相比),但似乎也完全禁止可空类型,尽管可空并不一定意味着现代版本的 C# 中的引用类型。

如果我愿意接受的值类型添加了非空一样int?DateTime?等而拒绝本身可空引用类型(如String),IList的等?是否可以通过这种方式定义约束?如果是怎么办?

我实际上很想学习实现这两种场景:当用作参数的类型必须同时是值和可为空时,以及何时接受可空值类型以及不可空值类型,我认为这些相关足以原谅提及两者,所以我很感激对第二个案例的谦虚评论,并选择一个答案,包括它作为更好的答案(假设另一个答案在其他方面不会真的更好),如果不止一个答案将是提交,我必须选择,但我现在真正需要的是第一种情况(总是需要一个既可以为空又是值类型的类型),我也相信第二种情况会鉴于第一个的知识,非常简单,更不用说坚持将两个问题粘在一起并不是一个好办法,所以我绝对会欣赏并接受只处理第一个案例的答案。

c# syntax nullable value-type generic-constraints

4
推荐指数
2
解决办法
2533
查看次数

我如何解释方法 compare(Function&lt;? super T,? extends U&gt; keyExtractor) 的参数?

方法的完整签名:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)

Run Code Online (Sandbox Code Playgroud)

我正在学习 lambda 表达式,我有这段代码比较员工列表并按姓名字段对它们进行排序:

List<Employee> employees = new ArrayList<>();

Collections.sort(employees, Comparator.comparing(Employee::getName));

Run Code Online (Sandbox Code Playgroud)

该代码工作正常,但我查看了文档中的 Comparator 功能接口,并且找到了方法“比较()”的签名。

comparing(Function<? super T,? extends U> keyExtractor)
Run Code Online (Sandbox Code Playgroud)

我没有得到比较()的参数。我怎么知道参数接受 lambda 表达式?以及如何解释约束:<? 超级T,?扩展 U> keyExtractor?

我知道 super 是什么意思?在层次继承中必须是类型 T 或以上,并且 ? 在层次继承中也必须是 U 类型及以下类型。但是我们怎么能在我的例子中转述呢?

可以这样解释: ? 继承链中必须是Employees及以上类型,并且继承链中name字段必须是Employees或以下类型?或者 ?必须是类型 Array List 及以上和 ? 必须是类型员工列表及以下?

java generics lambda java-8 generic-constraints

4
推荐指数
1
解决办法
514
查看次数

使用外部包中的通用成员处理不同结构的通用函数?

我想编写一个函数,可以将某些字段添加到 Firebase 消息结构中。有两种不同类型的消息MessageMulticastMessage,它们都包含相同类型的AndroidAPNS字段,但消息类型之间没有显式声明的关系。

我想我应该能够做到这一点:

type firebaseMessage interface {
    *messaging.Message | *messaging.MulticastMessage
}

func highPriority[T firebaseMessage](message T) T {
    message.Android = &messaging.AndroidConfig{...}
    ....
    return message
}
Run Code Online (Sandbox Code Playgroud)

但它给出了错误message.Android undefined (type T has no field or method Android)。我也不会写switch m := message.(type)( cannot use type switch on type parameter value message (variable of type T constrained by firebaseMessage))。

我可以写switch m := any(message).(type),但我仍然不确定这是否能达到我想要的效果。

我发现了一些对联合和类型约束感到困惑的人提出的其他问题,但我看不到任何有助于解释为什么这不起作用的答案(也许是因为我试图将它与结构而不是接口一起使用?)或者联合类型约束实际上有什么用处。

generics go generic-constraints union-types

4
推荐指数
1
解决办法
3596
查看次数