创建泛型数据类型方法
本文关键字:方法 数据类型 泛型 创建 | 更新日期: 2023-09-27 18:17:45
我有一个C#
应用程序,它有两个方法:
private void build_float_string() {
float[] mData = new float[1000];
Marshal.Copy(myPointer, mData, 0, 1000);
mData.ToList().ForEach(i => descriptor_string.Append(string.Format("{0}, ", i.ToString())));
}
结果是字符串1.0, 1.1, 1.2, 1.3, ...
。和:
private void build_byte_string() {
byte[] mData = new byte[1000];
Marshal.Copy(myPointer, mData, 0, 1000);
mData.ToList().ForEach(i => descriptor_string.Append(string.Format("{0}, ", i.ToString())));
}
结果是字符串1, 2, 3, 4, ...
。
或者数据是什么
我的问题是:由于这些方法是相同的-除了float
或byte
数据类型,我可以为此创建一个通用的模板方法吗?我确信C++
可以做到这一点,但我不知道在C#
中从哪里开始。
如果你不想要编译时类型安全,也有动态关键字(假设你使用c# 4.0或更高版本)
private void build_string<T>() where T : struct
{
try
{
T[] mData = new T[1000];
Marshal.Copy(myPointer,(dynamic) mData, 0, 1000);
descriptor_string.Append(String.Join(", ", mData.Select(item=>item.ToString()));
}
catch(RuntimeBinderException rbe)
{
// Handle case here where there is no suitable Marshal.Copy Method.
}
}
您可以使用类型类或类型参数,希望这对您有所帮助:
class Program
{
static void Main(string[] args)
{
DateTime dtNow = DateTime.Now;
Console.WriteLine("String of float: " + getTheString<float>(12.7f));
Console.WriteLine("String of DateTime: " + getTheString<DateTime>(dtNow));
Console.WriteLine("The type name for a float number: " + getTheTypeName(18.25f));
Console.WriteLine("The type name for a DateTime object: " + getTheTypeName(dtNow));
Console.WriteLine("the result of making an instance for a float type: " +
makeOneInstanceOfType(20.2f, typeof(float)));
Console.WriteLine("the result of making an instance for a DateTime type: " +
makeOneInstanceOfType(0, typeof(DateTime)));
//Using GetType() instead of typeof(..)
Console.WriteLine("the result of making an instance for a DateTime type: " +
makeOneInstanceOfType(0, typeof(DateTime)));
Console.ReadLine();
}
//Using the Type Parameter (T) for creating instances of T which T is your type,
//specified when calling the method
private static string getTheString<T>(T arg)
{
return arg+"";
}
//Using Type by calling the GetType() method of the object
private static string getTheTypeName(object arg)
{
return arg.GetType().FullName;
}
//Direct use of Type, creates a float and fills is with the value if theType is float,
//otherwise makes an instance of theType.
private static object makeOneInstanceOfType(float valIfFloat, Type theType)
{
object instance;
if(theType.IsEquivalentTo(typeof(float)))
{
instance = valIfFloat;
}
else
{
instance = Activator.CreateInstance(theType);
}
return instance;
}
}
我不认为你可以,因为没有通用重载的Marshal.Copy()
你可以让第二部分泛型,但是:
static StringBuilder BuildString<T>(IEnumerable<T> array, StringBuilder sb)
{
return array.Aggregate(sb, (s, f) => s.Append(string.Format("{0}, ", f.ToString())));
}
static StringBuilder BuildString<T>(IEnumerable<T> array)
{
return BuildString(array, new StringBuilder());
}
使用Aggregate
比ToList().ForEach()
更有效,因为后者实际上分配了一个中间列表。
private void build_the_string<T>() /* where T:struct */ {
T[] mData = new T[1000];
typeof(Marshal).GetMethod("Copy", BindingFlags.Static|BindingFlags.Public,
null, new Type[] { typeof(IntPtr), // or what myPointer really is,
typeof(T[]), typeof(Int32), typeof(Int32) }, null)
.Invoke(null, new object[] { myPointer, mData, 0, 1000 });
mData.ToList().ForEach(i => descriptor_string.Append(string.Format("{0}, ", i.ToString())));
}