Я хочу написать интерфейс, который позволяет свободу в реализации. В принципе, я не знаю, какие типы возвращаемых типов не являются параметрами. Я просто хочу, чтобы производные классы реализовали этот контракт с одинаковыми именами методов и номерами параметров.Ошибка компиляции с типами примитивов с реализациями общих методов интерфейса
Так что я могу сделать так:
public interface IImageRecognitionEngine<TFoo0, TFoo1, TFoo2, TFoo3>
{
TFoo0 Learn(TFoo1 param);
TFoo2 Recognize(TFoo3 param);
}
public class FooImageRecognitionEngine : IImageRecognitionEngine<byte[], string, List<double>, string>
{
public byte[] Learn(string param)
{
throw new NotImplementedException();
}
public List<double> Recognize(string param)
{
throw new NotImplementedException();
}
}
Но я бы гораздо больше предпочитают общие методы, а не весь интерфейс. Но я не понимаю, почему я могу это сделать:
public interface IImageRecognitionEngine2
{
TFoo0 Learn<TFoo0, TFoo1>(TFoo1 param);
TFoo2 Recognize<TFoo2, TFoo3>(TFoo3 param);
}
public class FooExampleClass
{
}
public class FooExampleClass2
{
}
public class Foo1ImageRecognitionEngine2 : IImageRecognitionEngine2
{
public FooExampleClass Learn<FooExampleClass, FooExampleClass2>(FooExampleClass2 param)
{
throw new NotImplementedException();
}
public FooExampleClass Recognize<FooExampleClass, FooExampleClass2>(FooExampleClass2 param)
{
throw new NotImplementedException();
}
}
Но с примитивными типами компилятор дает мне ошибки:
public class Foo2ImageRecognitionEngine2 : IImageRecognitionEngine2
{
public byte[] Learn<byte[], string>(string param)
{
throw new NotImplementedException();
}
public List<double> Recognize<List<double>, string>(string param)
{
throw new NotImplementedException();
}
}
Я не хочу, чтобы иметь возможность выбирать, какие типы использовать когда я создаю экземпляр объекта реализации класса. Например, я не хочу, чтобы написать реализацию, как это:
public class Foo2ImageRecognitionEngine2 : IImageRecognitionEngine2
{
public TFoo0 Learn<TFoo0, TFoo1>(TFoo1 param)
{
throw new NotImplementedException();
}
public TFoo2 Recognize<TFoo2, TFoo3>(TFoo3 param)
{
throw new NotImplementedException();
}
}
И, будучи в состоянии сделать это:
var fooEngine = new Foo2ImageRecognitionEngine2();
fooEngine.Learn<string, int>(52);
И это не работает также:
public interface IImageRecognitionEngine3
{
object Learn(object param);
object Recognize(object param);
}
public class Foo1ImageRecognitionEngine3 : IImageRecognitionEngine3
{
public byte[] Learn(string param)
{
throw new NotImplementedException();
}
public List<double> Recognize(string param)
{
throw new NotImplementedException();
}
}
Спасибо
Но ни одна из ваших реализаций фактически не удовлетворяет интерфейсу. Например, в объекте Learn (object param) я должен иметь возможность передавать что-либо как «param» (поскольку это объект типа), но ваш байт [] Learn (string param) позволяет мне передавать строку, поэтому не удовлетворяют интерфейсу. – Evk
Я думаю, что основным мотивом дженериков является то, что вы пытаетесь обойти. Вы должны * указать тип в конце концов. Я думаю, вы хотите создать «' 'Learn''' и' '' Recognize''' общие, а не метод или интерфейс. И тогда они могут принимать любые типы, которые вы хотите, и вы можете поддерживать интерфейс чистым (и сигнатурами метода)! – Ruskin
Есть ли у вас пример кода для обмена? Я не уверен, что понял. Я хочу использовать мой интерфейс в своей программе и передать хорошую реализацию при запуске, используя инъекцию зависимостей. Подобным образом я бы смог изменить реализацию, которую я использую очень легко. –