Как я могу создать временные объекты для передачи без явного создания класса? - PullRequest
13 голосов
/ 11 августа 2011

Мне часто приходится создавать класс в качестве контейнера для некоторых данных.Это только привыкает ненадолго, но я все еще должен создать класс.Например:

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.
}

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

Заранее спасибо.

Ответы [ 5 ]

27 голосов
/ 11 августа 2011

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

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

public void DoSomethingElse(Tuple<string, string, DateTime> data)
{
    // ...
}
5 голосов
/ 11 августа 2011

Правила гласят, что

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

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

2 голосов
/ 11 августа 2011

Кортеж - это чистый путь, но просто для того, чтобы вы знали , что C # не подводит вас и в противном случае, и чтобы ответить на вопрос, вот как 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, я не буду использовать это, я не прошу вас использовать это:)

0 голосов
/ 11 августа 2011
    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 и конструктор для List String ...

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

0 голосов
/ 11 августа 2011

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

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

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

...