Как принудительно установить значение определенного члена, когда хотите сериализовать для мыла - PullRequest
2 голосов
/ 21 сентября 2011

У меня есть этот метод:

[WebMethod]
public OpenAccountResult OpenAccount()
{
    OpenAccountResult test = new OpenAccountResult(/*true*/)//the true  here wont let the object to be serialized
    {
        //Success = true,
        AccountNumber = "test111"
    };
    return test;
}

OpenAccountResult фактически расширяет BaseSoapAnswer, поэтому я создал BaseSoapAnswer конструктор с одним bool параметром для Success, но я получил исключение, что объект с конструктором, которому нужен параметр, не может быть сериализован.

Исключение:

[InvalidOperationException: WebService.Services.TradingSystem.OpenAccountResult cannot be serialized because it does not have a parameterless constructor.]

Как заставить каждый экземпляр *Result объявлять bool Success. Я хочу сделать это путем реализации или наследования, потому что там будет много *Result, и я не хочу, чтобы другие программисты забыли об этом.

В нижней строке я хочу построить * Result таким образом, чтобы каждый экземпляр должен был устанавливать Success, и если он будет забыт, код не будет скомпилирован по соображениям безопасности (вы, вероятно, понимаете, что если Мне не нужно было бы сериализоваться, у меня не было бы проблем).

Спасибо.

Ответы [ 2 ]

3 голосов
/ 21 сентября 2011

Создайте дополнительный конструктор без параметров и пометьте его как устаревший («только для сериализации», true).Это позволит компилятору использовать конструктор, но ваш пользовательский код не будет компилироваться, когда вы пытаетесь использовать этот конструктор, даже с наследованием:

public abstract class MyBaseClass
{
    public bool Success { get; set; }

    [Obsolete("only for serialization", true)]
    public MyBaseClass(){}

    public MyBaseClass(bool success) { this.Success = success; }
}

public class MyConcreteClass
{
    [Obsolete("only for serialization", true)]
    public MyConcreteClass() : base() {}

    public MyBaseClass(bool success) : base(success) { /* whatever in this instance */ }
}

вы можете даже опустить базовый конструктор:

public abstract class MyBaseClass
{
    public bool Success { get; set; }

    public MyBaseClass(bool success) { this.Success = success; }
}

public class MyConcreteClass
{
    [Obsolete("only for serialization", true)]
    /* calling base constructor with false success parameter */
    public MyConcreteClass() : base(false) {}

    public MyBaseClass(bool success) : base(success) { /* whatever in this instance */ }
}
2 голосов
/ 21 сентября 2011

Для сериализации вам необходим конструктор без параметров. Но вы хотите, чтобы каждый Result имел Success = true?

public OpenAccountResult()
{
    Success = true;
}

Или, если это не всегда true и вы хотите указать Success, тогда вы можете просто иметь два конструктора:

// required for serialization
public OpenAccountResult()
{
}

// alternate constructor for you to use
public OpenAccountResult(bool successValue)
{
    Success = successValue;
}

Если вы не хотите устанавливать каждый конструктор Result, сделайте это в базовом классе. Если базовый класс не имеет свойства Success, создайте подкласс, из которого могут быть получены все ваши классы результатов:

public abstract class Result : BaseSoapAnswer
{
    public Result()
    {
        this.Success = true;
    }

    public bool Success { get; set; }
}

public class OpenAccountResult : Result 
// ...
public class AnotherResult : Result 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...