Обобщения и возвращаемые объекты класса

#c# #generics

#c# #обобщения

Вопрос:

Я пытаюсь вернуть объект класса, используя дженерики.

Это универсальный класс

 public class ClientBase <S>
{
    protected S CreateObject()
    {
        return default(S)  ;
    }
}
  

Вот как я пытаюсь это использовать…

 public class ClientUser : ClientBase <SomeClass>
{

    public void call()
    {
        var client = this.CreateObject();
        client.SomeClassMethod();
     }
}
  

Хотя я получаю объект SomeClassMethod() в объекте клиента, при запуске кода он выдает ошибку в строке:

клиент.SomeClassMethod();

Ошибка: «Ссылка на объект не установлена для экземпляра объекта». Я знаю, что в методе CreateObject() клиентской базы универсального класса чего-то не хватает; просто не могу понять это. Может ли кто-нибудь помочь мне здесь, пожалуйста?

Спасибо за ваше время…

Ответ №1:

default(S) где S ссылочный тип равен нулю. В вашем случае default(SomeClass) возвращает значение null. Когда вы пытаетесь вызвать метод по нулевой ссылке, именно тогда вы получаете свое исключение.

Вы пытаетесь вернуть экземпляр по умолчанию SomeClass ? Возможно, вы захотите использовать new() ограничение и return new S() вместо этого в своем универсальном классе, например:

 public class ClientBase<S> where S : new()
{
    protected S CreateObject()
    {
        return new S();
    }
}
  

Если S необходимо указать ссылочный тип, вы также можете ограничить его class :

 public class ClientBase<S> where S : class, new()
{
    protected S CreateObject()
    {
        return new S();
    }
}
  

Комментарии:

1. отредактировал мой вопрос … пропустил фактическую ошибку. 🙂

2. да, пытаюсь вернуть экземпляр. Я попробовал то, что вы положили. теперь я понимаю это… Целью вызова было вызвано исключение.

3. @user20358: Вполне вероятно, что какой-то другой код в вашей программе вызывает такое исключение.

4. @user20358: проверьте InnerException исключения TargetInvocationException на наличие фактического исключения

Ответ №2:

Посмотрите, что default(T) делает: http://msdn.microsoft.com/en-us/library/xwth0h0d.aspx

В вашем случае default(S) будет возвращено значение null (потому что это класс) — это не экземпляр класса.

Вам нужно либо вызвать new S() какой-либо другой S конструктор, либо переопределить CreateObject его в вашем производном классе.