简体   繁体   English

返回接口继承Generic方法中的类

[英]Return interface inherited classes in Generic method

I have 3 objects that are very similar with only a few differences 我有3个非常相似的对象,只有一些差异

public class Person
{
    public Person(ResourceObject resource)
    {
        // resource comes from an API provided by one
        // of our systems (i have no control over it)
        this.ResourceObject = resource;
    }

    // Resource
    internal ResourceObject ResourceObject { get; }

    // Similar properties
    public string ObjectID { get; }
    public string ObjectType { get; }
    public IEnumerable<string> PropertyNames { get; }

    // Person-specific property example - Organisation
    public string Organisation { get; set; }
}

public class Computer
{
    public Computer(ResourceObject resource)
    {
        // resource comes from an API provided by one
        // of our systems (i have no control over it)
        this.ResourceObject = resource;
    }

    // Resource
    internal ResourceObject ResourceObject { get; }

    // Similar properties
    public string ObjectID { get; }
    public string ObjectType { get; }
    public IEnumerable<string> PropertyNames { get; }

    // Computer-specific property example - OperatingSystem
    public string OperatingSystem { get; set; }
}

public class Group
{
    public Group(ResourceObject resource)
    {
        // resource comes from an API provided by one
        // of our systems (i have no control over it)
        this.ResourceObject = resource;
    }

    // Resource
    internal ResourceObject ResourceObject { get; }

    // Similar properties
    public string ObjectID { get; }
    public string ObjectType { get; }
    public IEnumerable<string> PropertyNames { get; }

    // Group-specific property example - Members
    public string Members { get; set; }
}

I currently have GetPerson , GetComputer and GetGroup methods that are working but they essentially do the same thing and then call one of the specific object constructors. 我目前有GetPersonGetComputerGetGroup方法正在工作,但他们基本上做同样的事情,然后调用一个特定的对象构造函数。 In an effort to dive into the world of Generics and Interfaces and learn more (as you do) i attempted to create a GetResource<T> method that would do the same job as those 3 methods without all the duplicate code. 为了深入了解泛型和接口世界并了解更多信息(正如您所做),我尝试创建一个GetResource<T>方法,该方法与没有所有重复代码的3种方法完成相同的工作。

I created the IResource Interface to identify common properties: 我创建了IResource接口来识别常见属性:

public interface IResource
{
    string ObjectID { get; }
    string ObjectType { get; }
    IEnumerable<string> PropertyNames { get; }
}

and then attempted to create a GetResource<T> method but got stuck at the return code: 然后尝试创建一个GetResource<T>方法,但卡在返回码:

    public static T GetResource<T>(string identity) where T : IResource
    {
        // get resource from system API

        // and then return T somehow?
        return new T(resourceObject);
    }

I thought of changing the return value from T to IResource but i'm still not sure how i would identify which class to return (Perhaps i need a base class? Resource perhaps). 我想把返回值从T更改为IResource但我仍然不确定如何识别要返回的类(也许我需要一个基类? Resource也许)。

The reason i turned to Generics for this specific situation is if the system API updates and suddenly has a new Location object i don't want to have to create a GetLocation method and then have 4 methods that do exactly the same thing except for one line of code. 我在这种特定情况下转向Generics的原因是,如果系统API更新并且突然有一个新的Location对象我不想创建一个GetLocation方法然后有4个方法完全相同的东西,除了一行代码

Is this the correct use case for Generics? 这是泛型的正确用例吗? and if so how can my method figure out what object to return? 如果是这样,我的方法怎么能找出要返回的对象?

Use a base class to hold common behavior. 使用基类来保存常见行为。

public abstract class Resource {

    protected Resource (ResourceObject resource) {
        // resource comes from an API provided by one
        // of our systems (i have no control over it)
        this.ResourceObject = resource;
    }

    // Resource
    internal ResourceObject ResourceObject { get; }

    // Similar properties
    public string ObjectID { get; }
    public string ObjectType { get; }
    public IEnumerable<string> PropertyNames { get; }
}

Derived classes 派生类

public class Person : Resource {

    public Person(ResourceObject resource):base(resource){
    }

    // Person-specific property example - Organisation
    public string Organisation { get; set; }
}

public class Computer : Resource {
    public Computer(ResourceObject resource) : base(resource) {
    }

    // Computer-specific property example - OperatingSystem
    public string OperatingSystem { get; set; }
}

public class Group : Resource {

    public Group(ResourceObject resource) : base(resource) {
    }

    // Group-specific property example - Members
    public string Members { get; set; }
}

Interfaces can't be initialized and thus trying to pass a constructor argument wont work. 接口无法初始化,因此尝试传递构造函数参数不起作用。

With the base class constraint the generic method becomes 使用基类约束,泛型方法成为

public static T GetResource<T>(string identity) where T : Resource {
    // get resource from system API

    // and then return T somehow?
    return (T) Activator.CreateInstance(typeof(T), resourceObject);
}

And used 并使用

Person person = GetResource<Person>("person_identity");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM