Замените тип объекта общими типами данных - Безопасность типов - PullRequest
0 голосов
/ 21 января 2020

Я разрабатываю систему, которая работает со многими модулями, у каждого из которых есть свои собственные наборы параметров. Каждое значение параметра может иметь общий тип данных (string, int, long, bytes, bool).
Для простоты объект параметра был определен в соответствии с:

public class Parameter : IParameter
{
    public string Name { get; set; }
    public object Value { get; set; }
    public string ValueType { get; set; }
}

Теперь обратите внимание, что Значение параметра объявляется с использованием типа «объект». Проблема в том, что мы теряем безопасность типов, которая подтверждает правильность типа при присваивании значения переменной. Скажите, что «Value» является «int», и мы должны были установить его как bool, VS будет жаловаться до и после компиляции.

Теперь мне было интересно, смогу ли я объявить все варианты «Value» следующим образом:

public int IIntInterface.Value { get; set; }
public string IStringInterface.Value { get; set; }
public bool IBoolInterface.Value { get; set; }

Но тогда, когда присваивается число / строка свойству «Value» Msgstr "," ValueType "сначала проверяется, чтобы проверить значение так, чтобы при использовании этого параметра был указан неправильный тип?

По сути, я пытаюсь получить поддержку безопасности типов для типа" объект " : -)

------------- Обновление ------------
Я пытался сделать это простым, но, похоже, я должен уточнить кое-что.
На стороне клиента мы получаем список IParameters. Этот список составляется с помощью чего-то подобного:

IPamameter a = new Parameter { Value = IntVal };
IPamameter b = new Parameter { Value = BoolVal };

var listParams = new Parameters();
listParams.Add(a);
listParams.Add(b);

Теперь я попытался использовать дженерики, но это не совсем работало, так как тип для параметра не может быть дженериком c (я думаю) :

class Program
{
    static void Main(string[] args)
    {
        int IntVal = 10;
        bool BoolVal = false;

        var a = new Parameter<int> { Value = IntVal };
        var b = new Parameter<bool> { Value = BoolVal };

        var listParams = new Parameters<T>();     // This does not work, it has to be an actual type, but I want all the params in the same list
        listParams.Add(a);
        listParams.Add(b);
    }
}

public class Parameter<T> : IParameter<T>
{
    public string Name { get; set; }
    public string ValueType { get; set; }
    public T Value { get; set; }
}

public class Parameters<T> : List<IParameter<T>>
{

}

public interface IParameter<T>
{
    string Name { get; set; }
    string ValueType { get; set; }
    T Value { get; set; }
}

1 Ответ

1 голос
/ 22 января 2020

Для того, чтобы хранить разнородные параметры в одном и том же списке, IParameter должен остаться не универсальным c и не иметь безопасности типов для свойства Value:

public interface IParameter
{
    string Name{get;}
    string ValueType{get;}
    object Value{get;}
}

Но, Вы могли бы предоставить реализацию generic c, которая обеспечивает безопасность типов в Value и , явно реализует версию Interfaces, просто возвращая generi c one.

public class Parameter<T> : IParameter
{
    public string Name{get;set;}
    public T Value {get;set;}
    public string ValueType {get => typeof(T).Name;}

    object IParameter.Value {get => this.Value;}
}

This позволит вашему клиентскому коду убедиться, что для правильных типов заданы правильные параметры, например:

var intParam = new Parameter<int>{Value = 10};
var strParam = new Parameter<string>{Value = "Hello World"};

var list = new List<IParameter>();
list.Add(intParam);
list.Add(strParam);

Это не удастся во время компиляции:

var badParam = new Parameter<int>{Value="Hello World"}; // Cannot implicitly convert type 'string' to 'int'

Вот работающая работа пример: https://dotnetfiddle.net/QSAUFR

Полезность этого кода несколько сомнительна. Но это, пожалуй, начало. Боюсь, вы окажетесь в общем c аде быстрее, чем вы думаете!

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