Условная компиляция в зависимости от версии платформы в C#

Это включает в себя кодек в соответствии с запросом, необходимые импорты и сутенером в соответствии с запросом.

import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SQLContext

// TODO Need a macro to generate for each Tuple length, or perhaps can use shapeless
implicit class PimpedRDD[T1, T2](rdd: RDD[(T1, T2)]) {
  def writeAsMultiple(prefix: String, codec: String,
                      keyName: String = "key")
                     (implicit sqlContext: SQLContext): Unit = {
    import sqlContext.implicits._

    rdd.toDF(keyName, "_2").write.partitionBy(keyName)
    .format("text").option("codec", codec).save(prefix)
  }
}

val myRdd = sc.makeRDD(Seq((1, "a"), (1, "b"), (2, "c")))
myRdd.writeAsMultiple("prefix", "org.apache.hadoop.io.compress.GzipCodec")

Одно тонкое отличие от OP состоит в том, что оно будет префикс <keyName>= к именам каталогов. Например,

myRdd.writeAsMultiple("prefix", "org.apache.hadoop.io.compress.GzipCodec")

дал бы:

prefix/key=1/part-00000
prefix/key=2/part-00000

, где prefix/my_number=1/part-00000 будет содержать строки a и b, а prefix/my_number=2/part-00000 будет содержать строку c ].

И

myRdd.writeAsMultiple("prefix", "org.apache.hadoop.io.compress.GzipCodec", "foo")

Дает:

prefix/foo=1/part-00000
prefix/foo=2/part-00000

Должно быть ясно, как отредактировать для parquet.

Наконец, ниже приведен пример для Dataset, что, возможно, лучше, чем использование Tuples.

implicit class PimpedDataset[T](dataset: Dataset[T]) {
  def writeAsMultiple(prefix: String, codec: String, field: String): Unit = {
    dataset.write.partitionBy(field)
    .format("text").option("codec", codec).save(prefix)
  }
}
24
задан Brian Tompsett - 汤莱恩 8 July 2016 в 15:35
поделиться

5 ответов

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

  1. Создайте различные конфигурации вашего проекта, по одной для каждой версии CLR, которую вы хотите поддерживать.

  2. Выберите символ, например VERSION2, VERSION3 и т. Д. Для каждой версии CLR.

  3. В каждой конфигурации определите один символ, связанный с ним, и отмените определение всех остальных.

  4. Используйте эти символы в блоках условной компиляции.

21
ответ дан p.s.w.g 28 November 2019 в 23:55
поделиться

Нет, любой встроил, но можно предоставить собственное.

Для этого определенного сценария, Вы могли бы хотеть инкапсулировать логику в (например), обертке (блокировка) класс, так, чтобы Вы не имели #if рассеянный через весь код; конечно, если Вы только делаете немного блокировки, это не могло бы стоить проблемы.

я использую различные конфигурации и/или проекты создать для множества платформ - т.е. protobuf-сеть сборки для.NET 2.0.NET 3.0, моно, CF 2.0, CF 3.5 с помощью этого приема. Код имеет #if, блоки на основе различных символов к управляющей логике - так, например, BinaryFormatter не доступны на CF, WCF только доступно с.NET 3.0, Delegate.CreateDelegate не находится на CF 2.0, и т.д.

6
ответ дан Marc Gravell 28 November 2019 в 23:55
поделиться

Вы можете использовать отражение, чтобы динамически проверять, доступен ли определенный тип, такой как ReaderWriterLockSlim (вместо использования препроцессора).

Это даст вам преимущество в том, что вы сможете развернуть одну версию своего продукта, и пользователи, имеющие (или обновляющие) .NET 3.5, получат выгоду от оптимизированного кода.

4
ответ дан Dirk Vollmar 28 November 2019 в 23:55
поделиться

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

2
ответ дан driAn 28 November 2019 в 23:55
поделиться

Если это все, что вам нужно было сделать, я полагаю, что вы могли бы использовать Environment.Version, но, как и в решении divo , оно, похоже, оставляет там много ненужного кода.

1
ответ дан Community 28 November 2019 в 23:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: