Как я могу создавать временные объекты, чтобы обойтись без явного создания класса?

Я часто обнаруживаю, что мне нужно создать класс как контейнер для некоторых данных. Он используется только кратко, но мне еще нужно создать класс. Вот так:

public class TempObject
{
    public string LoggedInUsername { get; set; }
    public CustomObject SomeCustomObject { get; set; }
    public DateTime LastLoggedIn { get; set; }
}


public void DoSomething()
{
    TempObject temp = new TempObject
    {
        LoggedInUsername = "test",
        SomeCustomObject = //blah blah blah,
        LastLoggedIn = DateTime.Now
    };
    DoSomethingElse(temp);
}

public void DoSomethingElse(TempObject temp)
{
    // etc...
}

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

public void DoSomething()
{
    var temp = new
    {
        LoggedInUsername = "test",
        SomeCustomObject = //blah blah,
        LastLoggedIn = DateTime.Now
    };
    // I have intellisense on the temp object as long as I'm in the scope of this method.
    DoSomethingElse(temp);
}

public void DoSomethingElse(????)
{
    // Can't get my anonymous type here. And even if I could I doubt I would have intellisense.
}

Есть ли лучший способ создать временный контейнер для группы разных типов или мне нужно определять классы каждый раз, когда мне нужен временный объект для группировки вещей вместе?

Спасибо заранее.

Ответ 1

Tuple может быть решением, которое вы ищете.

public void DoSomething() 
{
    var temp = Tuple.Create("test", "blah blah blah", DateTime.Now);
    DoSomethingElse(temp);
}

public void DoSomethingElse(Tuple<string, string, DateTime> data)
{
    // ...
}

Ответ 2

Правила утверждают, что

Вы не можете объявить поле, свойство, событие или тип возврата метода с анонимным типом. Точно так же вы не можете объявить формальный параметр метода, свойства, конструктора или индексатора как с анонимным типом.

Лично я бы просто кусал пулю на этом, чтобы сохранить целостность времени компиляции.

Ответ 3

The Tuple - это чистый путь, но , чтобы сообщить вам, что С# не позволяет вам даже в противном случае и отвечать на вопрос, так выглядит DoSomethingElse

private static void DoSomething(object temp)
        {
            var typedTemp = CastToType(temp, new
                            {
                                LoggedInUsername = "dummy",
                                SomeCustomObject = "dummy",
                                LastLoggedIn = DateTime.Now
                            });

            Console.WriteLine(typedTemp.LastLoggedIn);
        }

private static T CastToType<T>(object obj, T type)
        {
            return (T) obj;
        }

PS: Не используйте -1, я не буду использовать это, я не прошу вас использовать это:)

Ответ 4

Вы можете передавать анонимные типы, объявляя динамический параметр под С# 4. Тем не менее я бы не рекомендовал это, кроме частных методов. Вы теряете безопасность типа, IntelliSense и читаемость.

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

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

Ответ 5

    public class GenericObjs
    {
        private List<object> objs = new List<object>();
        public List<object> Objs { get { return objs; } set { objs = value; } }
        public GenericObjs(List<object> Objs) { objs = Objs; }
    }

Вы можете включить List String и конструктор для String List...

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