【问题标题】:C#: How to force a generic type to be an interface?C#:如何强制泛型类型成为接口?
【发布时间】:2019-07-23 16:15:28
【问题描述】:

以下代码有效:

public class Converter<T,M> : CustomCreationConverter<M>  
    where T : new()
    where M : class

但是,这是我想做的:

public class Converter<T,M> : CustomCreationConverter<M>  
    where T : new()
    where M : interface

是否有可能与此等价?

指定可以将 T 转换为 M 的约束在我的特定情况下也足够了。

为了澄清,我不是在寻找使T实现一些特定接口的能力。

有人可能会尝试将此问题标记为“Force generic interface implementation in C#”的重复问题。以下是我认为不值得将我的问题标记为重复的原因:

  1. 这个问题已经超过 8 年了
  2. 当发布答案的人发现发布问题的人实际上想知道如何实现特定接口时,问题就解决了
  3. 如果通过约束无法做到这一点,则可能有解决方法

我尝试这样做的原因是因为我尝试使用 Json.NET's JsonConverter Class 创建多个自定义 JSON 转换器。

public class Converter<T,M> : CustomCreationConverter<M>  
    where T : new()
{
    public override bool CanRead => base.CanRead;

    public override bool CanWrite => base.CanWrite;

    public override bool CanConvert(System.Type objectType)
    {
        return base.CanConvert(objectType);
    }

    public override M Create(System.Type objectType)
    {
        return new T(); //Cannot implicity convert type 'T' to 'M'
    }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
    {
        return base.ReadJson(reader, objectType, existingValue, serializer);
    }

    public override string ToString()
    {
        return base.ToString();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        base.WriteJson(writer, value, serializer);
    }
}

我可以为我需要转换器的每个课程执行上述操作或public class MyClassConverter : CustomCreationConverter&lt;IMyClass&gt;{}。只是想保持干燥!

【问题讨论】:

  • 类型是类还是接口为什么重要?我的意思是,知道它为什么重要可能会告诉我们您希望利用这些知识完成什么,我们可能会更好地提出适当的替代方案。
  • 泛型中的约束是为了实现一个功能,在遵守点规则之前它们来自哪里有什么关系。您还没有解释接口在您的情况下实现了什么具体的事情

标签: c# generics interface polymorphism


【解决方案1】:

指定可以将 T 转换为 M 的约束在我的特定情况下也足够了。

可以进行约束,其中 T 必须从另一个参数指定的类型派生。

where T : M

【讨论】:

  • 谢谢,你是对的。此外,如果其他人偶然发现此信息,可以在docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… 找到此信息。我是在你回答后才找到的。
  • 这并不能回答您提出的问题,在这种通用约束下,您将如何确保 M 始终是一个接口,因此 T 始终是一个接口。泛型始终保持编译时验证,因此在运行时不会发生任何新情况
  • @MrinalKamboj 我并没有要求 T 总是一个接口,只是它实现了 M。M 是我想要成为一个接口的东西。这个答案要求 T 是 M 的实现,这意味着 M 必须是接口或基类。你是正确的,这个“不回答问题”,因为它并没有明确强制 M 成为一个接口,但它对于其他想要这个问题的答案的人来说很有用。
  • 您的假设在这里不正确 M 不必是接口/基类,在泛型约束方面它也可以是同一个 T 类,因此问题仍然存在,因为您不能保证它的任何东西根据。这意味着 T 和 M 可以是同一个类并且代码不会抱怨
【解决方案2】:

where 泛型类型约束上的 documentation 告诉您可以指定哪些约束。

泛型定义中的 where 子句指定对在泛型类型、方法、委托或本地函数中用作类型参数的实参的类型的约束。约束可以指定接口、基类,或者要求泛型类型是引用、值或非托管类型。它们声明类型参数必须具备的能力。

鉴于此,我相信您的问题的答案是否定的,没有办法具体说明泛型类型参数是任何接口。

【讨论】:

  • 谢谢,我在发布之前确实阅读了文档。不过,Microsoft 的文档并不总是很全面。
  • 文档确实很清楚,它清楚地说明了约束可以包含哪些内容,并且由于无法定义“任何接口”,因此无法使用它
  • @MrinalKamboj 链接的文档不是可能限制的完整列表。
猜你喜欢
  • 2014-02-04
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 2019-07-21
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多