【问题标题】:Generics where T is class implementing interfaceT 是实现接口的类的泛型
【发布时间】:2018-11-30 04:16:30
【问题描述】:

我有一个界面:

interface IProfile { ... }

...还有一个班级:

[Serializable]
class Profile : IProfile 
{ 
  private Profile()
  { ... } //private to ensure only xmlserializer creates instances
}

...和一个有方法的经理:

class ProfileManager
{
  public T Load<T>(string profileName) where T : class, IProfile
  {
    using(var stream = new .......)
    {
      var ser = new XmlSerializer(typeof(T));
      return (T)ser.Deserialize(stream);
    }
  }
}

我希望这样使用方法:

var profile = myManager.Load<Profile>("TestProfile"); // class implementing IProfile as T

...并在此引发编译时错误:

var profile = myManager.Load<IProfile>("TestProfile"); // NO! IProfile interface entered!

但是一切都可以编译,XmlSerializer 只会抛出运行时错误。

我认为where T : class 会确保只接受类类型?

如果输入IProfile(或其他继承自IProfile的接口),是否可以让编译器抛出错误,并且只接受实现IProfile的类型类?

【问题讨论】:

  • XmlSerializer 抛出了什么错误?
  • @Default 没关系。这里的问题是T 可以是一个接口,即使有一个class 约束。
  • @Default: InvalidOperationException{"IProfile 无法序列化,因为它没有无参数构造函数"}

标签: c# .net generics compact-framework


【解决方案1】:

根据MSDN类表示T必须是引用类型;这也适用于任何类、接口、委托或数组类型。

一种解决方法是要求 T 实现无参数构造函数:

where T : class, IProfile, new()

【讨论】:

  • 是的,我想到了,除了 C# 希望构造函数是公共的。 :(
  • @Nautious 唯一的其他方法可能是使用代码合约
  • 也许另一种可能是创建一个抽象基类并将约束设置为基类而不是接口?
  • 那行不通,因为 Load(...) 仍然会编译并在运行时抛出异常。使用 new() 是最好的解决方法。
  • @zmbq 啊,是的,我真的没有考虑清楚。
【解决方案2】:

为我工作

public interface IUser
{
    int AthleteId { get; set; }
    string GivenName { get; set; }
    string FamilyName { get; set; }         
    bool IsActive { get; set; }
}

public  class DjsNameAutoSearch<Result, User> : where User : class, IUser, new()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    相关资源
    最近更新 更多