2016-08-14 6 views
0

Я хотел бы знать, есть ли простой способ, с помощью которого я могу упростить создание универсального метода, который принимает общий абстрактный класс. Это выглядит следующим образом:Общий метод с общим классом в C#

public J Read<T, M, J>(string fileName) where T : FileAccess<M, J> where M : Accessor where J : new() { 
     /*More Code... return J*/ 
    } 

FileAccess Класс принимает те же общие «аргументы».

public abstract class FileAccess<T, M> : IDisposable where T : Accessor where M : new() {/* More Code*/} 

И есть другие классы, реализующие этот абстрактный класс. например

public class StateAccess : FileAccess<XMLAccessor, List<Data>> {/*More Code*/} 

В большинстве случаев C# достаточно умен, чтобы понять это другие общие типы, которые вы используете, так что вам не придется писать их. Я думал, что это будет работать так же, и он будет в конечном итоге что-то вроде этого:

Read<StateAccess>("state"); 

Но вместо того, чтобы это то, что я должен сделать для того, чтобы заставить его работать:

Read<StateAccess, XMLAccessor, List<Data>>("state"); 

Даже если я уже сделал класс StateAccess, который использует XMLAccessor и список данных.

Метод Read будет использоваться с другими классами, которые наследуются от FileAccessor. Итак, мой вопрос: как я могу заставить свой код работать, поэтому я в итоге получаю это?

Read<StateAccess>("state"); 
Read<OtherAccess>("otherFileName"); 

Благодарим вас за продвижение.

+1

Я не думаю, что это возможно. В C# вам нужно либо объявить _all_ generic arguments, либо _none_ (если компилятор может самостоятельно вывести _all_ аргументы). Объявить только подмножество требуемых аргументов не разрешено в C#. –

+0

Ну, это печальные новости. Есть ли способ изменить метод, чтобы он знал, что общий должен быть не-абстрактный класс и что класс является не общим? –

ответ

2

Комментарий Рене - вы не можете заключить здесь подмножество общих аргументов.

Что вы можете сделать (при условии, что ваш метод Read не делает ничего с общим типом M) что-то вроде этого:

interface IReadableFileAccess<J> { ... // methods that Read needs... } 

Затем сделайте FileAccess или StateAccess реализовать IReadableFileAccess и изменить подпись Read чтобы:

J Read<J>(IFileAccess<J> access, String fileName, ... whatever ...) { ... } 

, к которому вы можете просто передать экземпляр StateAccess, который закрыт для J:

Read(someStateAccess, "fileName") 

Примечание: «Закрыто для J» выше означает, что StateAccess не является универсальным для J- указан тип для J и, следовательно, выводима.

+0

это сработало, большое спасибо. –

Смежные вопросы