【发布时间】:2020-04-08 15:01:28
【问题描述】:
我想要两个这样的转换器:
public class PacMan<T2> where T2 : new()
{
public static List<T1> ArrayToList<T1>(T2[] array)
{
var list = new List<T1>(array.Length);
for (int i = 0; i < array.Length; i++) list.Add(array[i]);
return list;
}
public static T2[] ListToArray<T1>(List<T1> list)
{
var array = new T2[list.Count];
for (int i = 0; i < list.Count; i++) array[i] = list[i];
return array;
}
}
其中T1 是一个类,T2 是一个结构。类和结构成员都具有相同的名称和类型。有了以上内容,我在第一种方法的list.Add(array[i]) 和第二种方法array[i] = list[i] 中得到了红色波浪形,所以这些方法不起作用。最简单的方法是什么?
编辑
课程如下:
public class PerSec : INotifyPropertyChanged
{
string yq;
float eps, nav, cash, debt;
public string YQ { get => yq; set { yq = value; OnPropertyChanged(); } }
public float EPS { get => eps; set { eps = value; OnPropertyChanged(); } }
public float NAV { get => nav; set { nav = value; OnPropertyChanged(); } }
public float Cash { get => cash; set { cash = value; OnPropertyChanged(); } }
public float Debt { get => debt; set { debt = value; OnPropertyChanged(); } }
#region Notify Property Changed Members
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
#endregion
}
这是结构:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PerSecStruct
{
//23 bytes
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
public string YQ;
public float EPS;
public float NAV;
public float Cash;
public float Debt;
}
编辑
在第二种方法中,我现在有这些:
public static T2[] ListToarray<T1>(List<T1> list)
{
var structFields = typeof(PerSecStruct).GetFields(BindingFlags.Instance | BindingFlags.Public);
var classFields = typeof(PerSec).GetProperties(BindingFlags.Instance | BindingFlags.Public);
classFields = classFields.Where(x => structFields.Select(y => y.Name).Contains(x.Name)).ToArray();
var fieldsDictionary = structFields.Zip(classFields, (k, v) => new { StructField = k, ClassField = v }).ToDictionary(x => x.StructField, x => x.ClassField);
var array = new T2[list.Count];
for (int i = 0; i < list.Count; i++)
{
var psStruct = array[i];
var psClass = list[i];
foreach (var entry in fieldsDictionary)
{
var value = entry.Value.GetValue(psClass);
entry.Key.SetValue(psStruct, value);
}
}
return array;
}
这条entry.Key.SetValue(psStruct, value); 行不工作,所以数组的元素有它们的默认值(null/0)。
编辑
如果我使用__makeref(array[i]),如 petelids 所述的here,它会起作用。有了它,我可以这样做:
public static T2[] ListToarray<T1>(List<T1> list)
{
var fields = typeof(T2).GetFields();
var properties = typeof(T1).GetProperties();
var array = new T2[list.Count];
for (int i = 0; i < list.Count; i++)
{
foreach (var field in fields)
{
var value = properties.First(x => x.Name == field.Name).GetValue(list[i]);
field.SetValueDirect(__makeref(array[i]), value);
}
}
return array;
}
我不需要那些绑定标志!并且要转换回列表,我必须用其他方法做到这一点:
public static List<T1> ArrayToList<T1>(T2[] array) where T1 : new()
{
var fields = typeof(T2).GetFields();
var properties = typeof(T1).GetProperties();
var list = new List<T1>(array.Length);
for (int i = 0; i < array.Length; i++)
{
var obj = new T1();
foreach (var property in properties)
{
var value = fields.First(x => x.Name == property.Name).GetValue(array[i]);
property.SetValue(obj, value);
}
list.Add(obj);
}
return list;
}
【问题讨论】:
-
将鼠标悬停在红色波浪线上时,出现什么错误?
-
另外,您的问题到底是什么?将数组转换为列表就像编写
var list = new List<T>(array);一样简单,反之亦然var array = list.ToArray(); -
我建议你看看
AutoMapper。非常方便的用于转换的 c# 库。 -
@EmonHaque 为什么不呢?