Присвоение объекта свойству типа объекта - PullRequest
0 голосов
/ 06 февраля 2020

После долгих осмотров (включая ПОДОБНЫЕ, но не одни и те же вопросы), я надеюсь, что мой вопрос будет иметь смысл, и кто-то может помочь мне решить эту проблему.

У меня много классов, скажем ClassA, ClassB, Class C et c и все они существуют по определенным c причинам. У меня есть другой класс, который используется для целей тестирования, и он включает в себя два свойства, которые устанавливаются следующим образом:

  public class Test : Countable<TestScenario>
  {


    //test completed
    public bool completed { get; set; } = false;

    //break or error (stop further execution) or not
    public bool breakOnError { get; set; } = true;

    //test result
    public bool success { get; set; } = false;

    //what did we test
    public string testCase { get; set; } = string.Empty;

    //what data we got as result
    public object testDataResult { get; set; }

    public Test()
    {
    }

   }

Моя проблема заключается в следующем: я создаю экземпляр класса, то есть Test myTest = new Test (); et c и мне нужно назначить класс, скажем, myResult (содержащий десятки свойств со значениями).

Мне нужно сделать (что-то вроде) это:

    Test myTest = new Test();
     myTest.testDataResult = myResult;

Это Можно предположить, что позже, если, например, существует myResult.SomeProperty со значением 18, я хотел бы видеть его из myTest.testDataResult.SomeProperty, т.е.

Console.WriteLine(myTest.testDataResult.SomeProperty.ToString());
//18

Возможно ли это? Просматривая все вокруг Binaryformatters и Reflection, один пример казался также хорошим (https://www.codeproject.com/Articles/1111658/Fast-Deep-Copy-by-Expression-Trees-C-Sharp), упомянутым здесь как ссылка в SO ( Более быстрое глубокое клонирование ), но я не мог сделать это, выше моего уровня опыта.

Может ли кто-нибудь помочь мне, пожалуйста, с рабочим примером?

Ответы [ 3 ]

0 голосов
/ 06 февраля 2020

Я предполагаю, что самый простой способ сделать это - сделать ваш класс Test обобщенным c:

public class Test<TResult> : Countable<TestScenario>
{
  // ... the test outcome properties listed above
  public TResult testDataResult { get; set; }
  // ... constructor
}

Это позволит вам получить доступ ко всем свойствам ваших экземпляров результатов тестовых данных без какого-либо черного маги c.

0 голосов
/ 06 февраля 2020

объект является классом, как и большинство других. Вы можете наследовать от него, создавать экземпляры его объектов (но вы делаете это редко), объявлять переменную этого типа. Тем не менее, существует два специальных правила, обусловленных его особой исторической / проектной позицией:

  1. Каждый отдельный класс неявно или явно наследуется от объекта. Если вы не определили базовый класс, объект применяется неявно. Если вы определили базовый класс, вам просто нужно go отойти достаточно далеко от его цепочки наследования, и вы найдете объект. Тип объекта - это root иерархии каждого класса.

  2. В то время как Numeri c Типы, структуры и co не наследуются от Object, их можно заключить в объект. Это выглядит очень похоже, но есть различия в деталях.

В результате каждый мыслимый тип в. NET может быть присвоен переменной типа object. В любом случае это либо объект, так что наследование вступает во владение, либо его можно объединить в один. Теперь мы больше не используем объект как тип. Хотя вы можете присвоить объекту что угодно, при этом вы теряете проверки типов времени компиляции. И это очень важно потерять. Я бы никогда не пожертвовал им, если бы мог помочь.

Дженерики против объекта

Использование объекта как типа вышло из-под контроля с дженериками. оператор блокировки является одним из редких случаев, когда вы все еще создаете переменную типа object и явно создаете isntance объекта. Вы найдете объект типа, используемый для sender в обработчиках событий (это 50% конвекция, 50% полезность). Почти везде мы используем обобщенные значения.

Универсальные элементы были добавлены в Framework и язык специально, чтобы избежать необходимости прибегать к к объекту как типу переменной. И я выбрал «прибегнуть к» очень намеренно. Коллекции Generi c, такие как List<T>, Queue<T> и Dictionary<TKey,TValue>, заменили ранее созданные c, такие как Queue, HashTable и те, которые мы использовали вместо списка.

Мы не можем на самом деле выяснить, какова ваша цель. Однако это звучит очень похоже на проблему XY, просто потому, что использование объекта в качестве типа переменной является его частью.

0 голосов
/ 06 февраля 2020

Если я правильно понял, мне кажется, что вы что-то путаете.

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

Вы должны сделать что-то вроде этого:

(SomeClss () myTest.testDataResult) .Property1

По этой причине вам следует попытаться ввести тип, который может быть интерфейсом, для описания минимального набора необходимых вам методов и свойств. Если ты не можешь, нет проблем, тебе просто нужно сыграть. Имейте в виду, что последний подход может создать sh во время выполнения, если вы выберете неправильный тип, тогда как первый позволяет обнаруживать ошибки во время компиляции.

...