小编And*_*son的帖子

便携式类库:推荐替代[Serializable]

我正在将.NET Framework C#类库移植到可移植类库.一个反复出现的问题是如何处理使用该[Serializable]属性修饰的类,因为此属性不是可移植类库子集的一部分.相反,可移植类库子集中的序列化功能似乎由DataContractAttribute覆盖.

  • 为了在可移植类库中保留尽可能多的功能,[Serializable][DataContract]属性替换就足够了(暗示所有需要序列化的字段和属性也需要进行修饰[DataMember])?
  • 什么(如果有的话)我无法用这种方法做我可以做的[Serializable]应用?
  • 是否有一种侵入性较小的方法?

鉴于[DataContract][DataMember]使用,我正在考虑改变代码沿着以下行.这种方法有明显的缺陷吗?有没有办法制定同样的东西,而不是那么冗长?

#if PORTABLE
    [DataContract]
#else
    [Serializable]
#endif
    public class SerializableClass : SerializableBaseClass
    {
       ...
#if !PORTABLE
        protected SerializableClass(SerializationInfo info, StreamingContext context)
             : base(info, context)
        {
        }
#endif
        ...
#if PORTABLE
        [DataMember]
#endif
        private Type1 _serializableField;

#if PORTABLE
        [DataMember]
#endif
        private Type2 SerializableProperty { get; set; }

        ...
    }
Run Code Online (Sandbox Code Playgroud)

c# serialization datacontract serializable portable-class-library

43
推荐指数
2
解决办法
3万
查看次数

如何实现返回Task <T>的接口方法?

我有一个界面

interface IFoo
{
  Task<Bar> CreateBarAsync();
}
Run Code Online (Sandbox Code Playgroud)

有两种方法可以创建Bar,一种是异步,另一种是同步.我想为这两种方法中的每一种提供接口实现.

对于异步方法,实现可能如下所示:

class Foo1 : IFoo
{
  async Task<Bar> CreateBarAsync()
  {
    return await AsynchronousBarCreatorAsync();
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,我该如何实现Foo2使用同步方法创建的类Bar

可以实现同步运行的方法:

  async Task<Bar> CreateBarAsync()
  {
    return SynchronousBarCreator();
  }
Run Code Online (Sandbox Code Playgroud)

然后,编译器将警告不要async在方法签名中使用:

这种异步方法缺少"等待"运算符并将同步运行.考虑使用'await'运算符等待非阻塞API调用,或'await Task.Run(...)'在后台线程上执行CPU绑定工作.

或者,我可以实现显式返回的方法Task<Bar>.在我看来,代码看起来不那么可读:

  Task<Bar> CreateBarAsync()
  {
    return Task.Run(() => SynchronousBarCreator());
  }
Run Code Online (Sandbox Code Playgroud)

从性能的角度来看,我认为这两种方法的开销大致相同,或者?

我应该选择哪种方法; async同步实现方法或显式包装同步方法调用Task

编辑

我正在开发的项目实际上是一个.NET 4项目,其中包含来自Microsoft Async NuGet包的async/await扩展.在.NET 4上,可以替换为.我有意识地在上面的例子中使用了.NET 4.5方法,希望能让主要问题更加清晰.Task.RunTaskEx.Run

.net c# asynchronous task-parallel-library async-await

38
推荐指数
4
解决办法
9753
查看次数

使用相同元素的多个副本初始化C#数组

在C++标准模板库(STL)中,可以使用此构造函数创建一个由同一元素的多个副本组成的向量:

std::vector<double> v(10, 2.0);
Run Code Online (Sandbox Code Playgroud)

这将创建10个双精度矢量,最初设置为2.0.

我想在C#中做类似的事情,更具体地说,创建一个n个双精度数组,所有元素都初始化为相同的值x.

我提出了以下单线程,依赖于泛型集合和LINQ:

double[] v = new double[n].Select(item => x).ToArray();
Run Code Online (Sandbox Code Playgroud)

但是,如果局外人会阅读此代码,我认为代码实际上不会立即显现.我也关注性能,我想通过for循环初始化数组元素会更快(虽然我没有检查过).有人知道更清洁和/或更有效的方法来执行此任务吗?

c# linq arrays

21
推荐指数
2
解决办法
2万
查看次数

快速计算:可以提高准确性而不会损失太多性能?

我正在尝试快速的Exp(x)函数,这个函数之前在这个回答中描述了一个提高C#计算速度的SO问题:

public static double Exp(double x)
{
  var tmp = (long)(1512775 * x + 1072632447);
  return BitConverter.Int64BitsToDouble(tmp << 32);
}
Run Code Online (Sandbox Code Playgroud)

表达式使用一些IEEE浮点"技巧",主要用于神经集.该功能比常规Math.Exp(x)功能快约5倍.

不幸的是,相对于常规Math.Exp(x)函数,数值精度仅为-4% - + 2%,理想情况下,我希望精度至少在亚百分比范围内.

我已经绘制了近似和常规Exp函数之间的商,并且从图中可以看出,相对差异似乎以几乎恒定的频率重复.

快速和常规exp函数之间的商数

是否有可能利用这种规律性来进一步提高"快速exp"功能的准确性而不会显着降低计算速度,或者精度提高的计算开销是否会超过原始表达式的计算增益?

(作为旁注,我也尝试过在同一个SO问题中提出的替代方法之一,但这种方法在C#中似乎没有计算效率,至少在一般情况下并非如此.)

5月14日更新

根据@Adriano的要求,我现在已经执行了一个非常简单的基准测试.我已经使用每个替代exp函数对[-100,100]范围内的浮点值执行了1000万次计算.由于我感兴趣的值范围从-20到0,我还明确列出了x = -5处的函数值.结果如下:

      Math.Exp: 62.525 ms, exp(-5) = 0.00673794699908547
Empty function: 13.769 ms
     ExpNeural: 14.867 ms, exp(-5) = 0.00675211846828461
    ExpSeries8: 15.121 ms, exp(-5) = 0.00641270968867667
   ExpSeries16: 32.046 ms, exp(-5) = 0.00673666189488182
          exp1: 15.062 ms, exp(-5) = -12.3333325982094
          exp2: 15.090 …
Run Code Online (Sandbox Code Playgroud)

c# performance floating-accuracy exp

20
推荐指数
4
解决办法
1万
查看次数

使用工具将Java转换为C#,还是手动?

我有一个Java项目,我想转换为C#,看完这里和其他地方后发现了一个工具,Sharpen.

但是,为了使其运行起来(我是Java的新手),上面链接的站点描述了抓取源代码并将其构建为Eclipse IDE的插件,我不想这样做,因为我通常不这样做做Java.

有谁知道是否存在独立的EXE,它可以简单地利用Sharpen来获取给定的Java项目并通过绞拧器将其转换为C#?或者Java和C#是否足够相似,以便将代码手动移植到.NET应该非常简单?

c# java eclipse-plugin sharpen-tool

18
推荐指数
1
解决办法
1万
查看次数

使用Parallel.For令人失望的性能

我试图通过使用来加快我的计算时间Parallel.For.我有一个带有8个内核的英特尔酷睿i7 Q840 CPU,但与顺序for环路相比,我只能获得4的性能比.这是否可以获得Parallel.For,或者可以调整方法调用以提高性能?

这是我的测试代码,顺序:

var loops = 200;
var perloop = 10000000;

var sum = 0.0;
for (var k = 0; k < loops; ++k)
{
    var sumk = 0.0;
    for (var i = 0; i < perloop; ++i) sumk += (1.0 / i) * i;
    sum += sumk;
}
Run Code Online (Sandbox Code Playgroud)

并行:

sum = 0.0;
Parallel.For(0, loops,
                k =>
                    {
                        var sumk = 0.0;
                        for (var i = 0; i < perloop; ++i) sumk += …
Run Code Online (Sandbox Code Playgroud)

c# performance task-parallel-library

18
推荐指数
3
解决办法
2万
查看次数

在可移植类库中实现自定义异常

在为.NET设计自定义异常时,MSDN提供了这些指南.特别是,指南声明了一个自定义异常:

  • 应该是可序列化的,即实现ISerializable和用[Serializable]属性装饰,和
  • 应该实现(de)序列化构造函数,即protected CustomException(SerializationInfo info, StreamingContext context).

然而,在便携式类库既不的SerializableAttribute,ISerializableSerializationInfo得到支持.

我应该如何在同时针对.NET Framework和一个或多个平台的可移植类库中充分设计自定义异常?

.net c# exception portable-class-library windows-store-apps

17
推荐指数
1
解决办法
1888
查看次数

用于Windows应用商店应用API的.NET中Emit.OpCodes的用途?

我正在考虑将第三方库移植到.NET for Windows Store应用程序.该库通过调用ILGenerator.Emit方法重载过度使用System.Reflection.Emit.OpCodes.

.NET for Windows Store Apps API中,包含了OpCode结构和OpCodes类,但没有ILGenerator类,并且我已经找不到替换.

我显然失去了一些东西,但:没有ILGenerator一流的,什么是包括的目的System.Reflection.Emit.OpCodeOpCodes.NET的Windows Store应用程序的API?

c# reflection.emit ilgenerator opcodes windows-store-apps

15
推荐指数
1
解决办法
475
查看次数

如何在将.NET库移植到PCL时解决缺少ICloneable接口的问题?

我正在将现有的.NET类库移植到可移植类库..NET库广泛使用ICloneable接口,该接口未包含在可移植子集中.

通常,我在.NET类库中遇到类似这样的类定义:

public class Foo<T> where T : ICloneable
{
    public void Bar(T item) {
        var x = item.Clone();
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如何将此代码成功移植到可移植类库中,我该怎么办?我是否必须重写Clone方法调用,或者是否有较少侵入性的解决方法?

我不能简单地删除泛型类型约束,where T : ICloneable因为该Bar方法将无法编译.

我可以编写一个替换接口来代替ICloneable在移植代码中使用:

public interface IPCLCloneable {
    object Clone();
}
Run Code Online (Sandbox Code Playgroud)

只要我只实现Foo<T>了实现的类,这就可以工作IPCLCloneable,但是它不能用于实现的核心库中的类型ICloneable,例如Array:

var x = new Foo<int[]>();  // Compilation error in PCL library
Run Code Online (Sandbox Code Playgroud)

(为了完整起见,应该指出ICloneable接口未在可移植子集核心库中显式实现,因为它不存在,但该object Clone()方法确实存在于可移植子集Array类中,因此对于数组实现,例如int[].)

我还有其他选择吗?

c# generics interface icloneable portable-class-library

15
推荐指数
1
解决办法
9935
查看次数

从异步方法返回输出时推荐的方法签名?

我有一个异步方法:

public async Task<BitmapSource> GetBitmapAsync(double[] pixels);
Run Code Online (Sandbox Code Playgroud)

假设我也有这个课程:

public class PixelData
{
    public double[] Pixels { get; }
}
Run Code Online (Sandbox Code Playgroud)

我现在想要创建一个生成BitmapSource输出的方便方法,使用上面的异步方法来完成工作.我可以提出至少三种方法来做到这一点,但对于我来说,从效率和可靠性的角度来看,我应该选择哪一种方法.

有人可以建议; 以下每种方法的优点和缺点是什么?

选项A创建一个返回以下内容Result的同步方法Task:

public BitmapSource GetBitmap(PixelData pixelData)
{
    return GetBitmapAsync(pixelData.Pixels).Result;
}
Run Code Online (Sandbox Code Playgroud)

选项B创建一个返回Task<BitmapSource>以下内容的同步(或它是异步?)方法:

public Task<BitmapSource> GetBitmap(PixelData pixelData)
{
    return GetBitmapAsync(pixelData.Pixels);
}
Run Code Online (Sandbox Code Playgroud)

选项C创建一个显式使用的异步方法await:

public async Task<BitmapSource> GetBitmapAsync(PixelData pixelData)
{
    return await GetBitmapAsync(pixelData.Pixels);
}
Run Code Online (Sandbox Code Playgroud)

.net c# async-await async-ctp windows-runtime

14
推荐指数
1
解决办法
329
查看次数