簡體   English   中英

如何正確實現通用接口方法?

[英]How to correctly implement generic interface method?

我正在嘗試實現通用接口方法,但不斷收到錯誤。 我正在粘貼代碼以更好地解釋我想要做什么。

我想要實現的是:基於一些輸入數據(SomeModelA,SomeModelB),我希望得到相同的返回類型(模板)。

namespace GenericInterfacePuzzle
{
    class Program
    {
        static void Main(string[] args)
        {
            var workerA = new WorkerA();
            var itemsBasedOnModelA = workerA.Get(new List<SomeModelA>());

            var workerB = new WorkerB();
            var itemsBasedOnModelB = workerB.Get(new List<SomeModelB>());
        }
    }

    public interface IWorker
    {
        Template Get<T>(List<T> someModels);
    }

    public class WorkerA : IWorker
    {
        public Template Get<SomeModelA>(List<SomeModelA> someModels)
        {
            ProcessModels(someModels);
            return new Template(); // let's say it's based on the result of ProcessModels
        }

        private void ProcessModels(List<SomeModelA> models)
        {
            var x = models.First();
        }
    }

    public class WorkerB : IWorker
    {
        public Template Get<SomeModelB>(List<SomeModelB> someModels)
        {
            ProcessModels(someModels);
            return new Template(); // let's say it's based on the result of ProcessModels
        }

        private void ProcessModels(List<SomeModelB> models)
        {
            var x = models.First();
        }
    }

    public class SomeModelA
    {
        public string Name { get; set; }
    }

    public class SomeModelB
    {
        public string Age { get; set; }
    }
    public class Template
    {
        // Irrevelant return type
    }
}

我想知道在WorkerA / WorkerB類的級別,我正在處理一個具體的模型,並基於我想要返回一個Template類實例問題是在調用Process的行中:

ProcessModels(someModels);

我收到一個錯誤說:

錯誤CS1503參數1:無法從SomeModelA的'System.Collections.Generic.List'轉換為GenericInterfacePuzzle.SomeModelA的'System.Collections.Generic.List'

任何反饋都會理解這里可能出現的問題,以及為什么在傳遞給函數時它不會識別模型類。

克里斯

1)您需要在接口級別定義泛型參數。 否則編譯器不知道T參數:

public interface IWorker<T> where T: SomeModel
{
    Template Get(List<T> someModels);
}

2)您需要制定一個約束,因為您可能不希望任何類型被賦予您的接口。 最好為你的模型創建一個基類,讓它們繼承它:

public abstract class SomeModel { ... }    

public class SomeModelA : SomeModel
{
    public string Name { get; set; }
}

public class SomeModelB : SomeModel
{
    public string Age { get; set; }
}

這樣它將允許您直接在將實現接口的類的聲明中指定模型(參見第3點)

3)現在你需要在子類中指定哪個模型屬於哪個workertype:

public class WorkerA : IWorker<SomeModelA>
{
    public Template Get(List<SomeModelA> someModels)
    {
        ProcessModels(someModels);
        return new Template(); // let's say it's based on the result of ProcessModels
    }

    private void ProcessModels(List<SomeModelA> models)
    {
        var x = models.First();
    }
}

public class WorkerB : IWorker<SomeModelB>
{
    public Template Get(List<SomeModelB> someModels)
    {
        ProcessModels(someModels);
        return new Template(); // let's say it's based on the result of ProcessModels
    }

    private void ProcessModels(List<SomeModelB> models)
    {
        var x = models.First();
    }
}

您還應該刪除Get方法中的通用規范!

public Template Get<SomeModelA>(List<SomeModelA> someModels)
                      ^
                      |
                   remove this

實現界面時已經指定了這個:

public class WorkerA : IWorker<SomeModelA>

4)最后一件事是你在main方法中測試:

var worker = new WorkerA();
var itemsBasedOnModelA = worker.Get(new List<SomeModelA>());

var workerB = new WorkerB();
var itemsBasedOnModelB = worker.Get(new List<SomeModelB>());
                           ^
                           |
                    this should be [workerB]!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM