-
2021-09-01 18:31:55
有时候我们需要一个函数返回多个值,网上更多是用out实现,我个人很喜欢用tuple方法。tuple是一个元组,最多支持7个元素,再多需要嵌套等方法实现。
使用元组定义函数的方法如下:
public static Tuple<string, string> TupleFun() { string[] T = { 'hello', 'world' }; Tuple<string, string> tup = new Tuple<string, string>(T[0], T[1]); return tup; }
元组还支持多种类型的值。
public static Tuple<string, int> TupleFun() { string T = ‘hello’; int q = 6; Tuple<string, int> tup = new Tuple<string, int>(T, q); return tup; }
在调用函数时,使用Item*来调用元组内的元素。
var tuple = TupleFun(); print(tuple.Item1); print(int.Parse(tuple.Item2));
更多相关内容 -
.net中前台javascript与后台c#函数相互调用问题
2021-01-01 13:13:18如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问JavaScript的已有变量? 4.如何在C#中访问JavaScript函数? 问题1答案如下: javaScript函数中执行C#代码中的函数: 方法一:1、首先建立... -
javascript函数中执行c#函数的方法
2020-12-26 11:55:101如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问JavaScript的已有变量? 4.如何在C#中访问JavaScript函数? 问题1答案如下: javaScript函数中执行C#代码中的函数: 方法一:1、... -
C#调用c++函数的dll文件,同时实现c++调用c#函数
2020-04-12 16:43:33解压后是两个项目,一个c++DLL,一个c#控制台。C#调用c++函数的dll文件,同时实现c++调用c#函数,解决了错误,可以正常运行。如果有其他问题,可以互相讨论。 -
[电子书] C#函数式程序设计 - 经典编程技术在现代项目中的应用 (英文版)
2013-03-30 18:55:49[Wrox] C#函数式程序设计 - 经典编程技术在现代项目中的应用 [Wrox] Functional Programming in C# Classic Programming Techniques for Modern Projects (E-Book) ☆ 出版信息:☆ [出版机构] Wrox [出版日期] ... -
C#实现向函数传递不定参数的方法
2020-09-03 18:24:39主要介绍了C#实现向函数传递不定参数的方法,涉及C#操作函数参数的相关技巧,非常具有实用价值,需要的朋友可以参考下 -
C#写的各种拟合函数
2020-10-08 03:30:22这是用C#写的用最小二乘法实现的各种拟合函数,包括了多项式拟合,指数函数拟合,对数函数拟合,幂函数拟合。本人菜鸟一枚,有错误的地方请多多指教。 -
c#函数库 函数详解
2012-11-05 16:50:58c#函数库 各类c#函数库详解 对c#初学者很有帮助 -
C# 函数多个返回值 解决办法
2020-04-20 17:36:41因为在获得结果时,属性是位于函数本身上,而这个信息丢失了。 综上,如果是数据比较大的返回值可以用引用类型,如果是数据比较小的返回值,使用频繁的话可以使用结构体,但是一次性的建议使用元组。对于public API...编程中经常遇到有多个返回值的情况,下面提供了几种方法供参考。
方法一:
GetPerson(out var Name, out var Age, out var Male); Debug.Log(Name + " " + Age + " " + Male);
public void GetPerson(out string name, out int age, out bool male) { name = "Jack"; age = 56; male = true; }
方法二:
var person = GetPerson(); Debug.Log(person.Name + " " + person.Age + " " + person.Male);
public struct Person { public string Name; public int Age; public bool Male; } public Person GetPerson() { return new Person() { Name = "Jack", Age = 56, Male = true }; }
方法三:
var person = GetPerson_(); Debug.Log(person.Name + " " + person.Age + " " + person.Male);
public (string Name, int Age, bool Male) GetPerson() { return ("Jack", 56, true); }
个人理解:
方法一使用了out,写起来也比较方便,但是会造成API的不容易理解,因为out更多被视为额外输出。
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/parameter-design?redirectedfrom=MSDN方法二使用了结构体, 结构体的还是能比较好的总结输出,但大量使用一次性类型会将代码弄得一团糟。
方法三使用了valueTuple,valueTuple的字段和结构体一样拥有描述性名字,用起来也比较方便,但是元组这个方案增加字段不是很方便。 TupleElementNames 属性只能由编译器赋予。如果返回类型上使用了反射,你将只能看到裸的 ValueTuple 结构体。因为在获得结果时,属性是位于函数本身上,而这个信息丢失了。
综上,如果是数据比较大的返回值可以用引用类型,如果是数据比较小的返回值,使用频繁的话可以使用结构体,但是一次性的建议使用元组。对于public API并且数据可能会被修改的话,可以使用结构体,非public的话可以使用元组,这样使用和修改都挺方便。out返回值更多被视为返回值的补充,不要把数据一股脑使用out返回。
-
C#_函数手册大全+c#公共函数
2013-10-25 10:50:35c#公共函数.doc C#_函数手册大全.doc -
C# 函数参数传递(按值和引用)
2018-11-30 15:12:21先来说下C#中的数据类型.分值类型和引用类型两大类. 值类型:直接存储数据的值,保存在内存中的stack(堆栈)中 引用类型:存储对值的引用,实际上存储的就是一个内存的地址.引用类型的保存分成两块,实际值保存在...先来说下C#中的数据类型.分值类型和引用类型两大类.
值类型:直接存储数据的值,保存在内存中的stack(堆栈)中
引用类型:存储对值的引用,实际上存储的就是一个内存的地址.引用类型的保存分成两块,实际值保存在托管堆(heap)中.实际值的内存地址保存在stack中
当使用引用类型时先找到stack中的地址,再找到heap中的实际值.
也就是说保存引用类型时要用到stack和heap,但使用引用类型时我们实际上只用到stack中的值,然后通过这个值间接的访问heap中的值
C#预定义的简单类型,像int,float,bool,char都是值类型,另外enum(枚举),struct(结构)也是值类型
string,数组,自定义的class就都是引用类型了.其中的string是比较特殊的引用类型.C#给它增加个字符恒定的特性.
C#函数的参数如果不加ref,out这样的修饰符显式申明参数是通过引用传递外,默认都是值传递.
这里要注意的一个问题是,参数的类型是值类型还是引用类型和传参数时用值传递还是引用传递是两个不同的概念.
假如有void FunTest(int [] array) 和void FunTest(int a)
这两个函数.参数array是引用类型,a是值类型.但是他们传递时都是按值传递.我们来举个例子说明下
按值传递参数:
class Program
{
public static void ChangeInt(int num)
{
num = 123;
}
public static void ChangeArray(int[] array)
{
array[0] = 10;
array = new int[] { 6, 7, 8, 9 };
}
static void Main(string[] args)
{
int anum = 1;
int[] aarray = { 1, 2, 3 };
ChangeInt(anum);
ChangeArray(aarray);
Console.WriteLine("value of num: " + anum);
Console.Write("value of aarray: ");
foreach (int i in aarray)
Console.Write(i + " ");
}
}
结果是:value of anum : 1
value of aarray :10 2 3
可能看到结果会有点奇怪.我们一般认为值传递就是把值拷贝一份,然后不管在函数中对传入的参数做啥改变,参数之前的值不会受啥影响,所以anum没有变成123,仍然是1
但是aarray[0]为啥却变成10了呢?
前面我们有说到引用类型在内存中是保存为两个部分,一个是stack中的内存地址,另一个是heap中的实际值.用时我们只直接用stack中的值,我们假如stack中的值为0xabcdefgh
,就说是aaraay指向它吧. 那么我们按值传递时就是把这个stack的值拷贝成另一份就假如是array指向它吧.跟拷贝anum的值1一样.但是我们操作内存地址这样的值时不会像整数一样直接操作它,而只会通过它去找heap中的实际值.
于是我们array[0] = 10.改变了实际上还是heap中数组的值了. 但array = new int []
{6,7,8,9}没有对之前传的aarray产生影响.这个操作的意义是在heap中重新开辟一块内存,保存着值6,7,8,9.
这这块内存的地址赋给array,于是它之前的值0xabcdefgh被改写了.但aarray指的值stack值仍没变,仍是0xabcdefgh按引用传递参数
可以用out或ref显式指定.它们大部分时候可以通用,只是有一点细小区别.
先用ref 来举例吧,还用上面的例子,只是加个了关键字ref
class Program
{
public static void ChangeInt(ref int num)
{
num = 123;
}
public static void ChangeArray(ref int[] array)
{
array[0] = 10;
array = new int[] { 6, 7, 8, 9 };
}
static void Main(string[] args)
{
int anum = 1;
int[] aarray = { 1, 2, 3 };
ChangeInt(ref anum);
ChangeArray(ref aarray);
Console.WriteLine("value of num: " + anum);
Console.Write("value of aarray: ");
foreach (int i in aarray)
Console.Write(i + " ");
}
}
结果是:value of anum : 123
value of aarray :6 7 8 9
跟按值传递的结果完全不同吧
num = 123我们是容易理解.我们再来说下aarray的值为啥变了吧
按引用传递时aarray指向的stack中的值不会复制一份,而是直接传过去.这样array[0]= 10这样赋值时也同样改变了heap中 1 2 3
的值,变为10 2 3,如果没有array = new int [] {6,7,8,9}
这个语句,则它的结果跟上面按值传递是完全一样的.但有个这句话后就不一样,我们知道上面说了它的含义,在heap中开辟一块新内存值是6 7 8 9,而aarray指向的stack的值被改写了,改为指向保存6 7 8 9的内存地址了.那含有10 2
3的那一块内存其实还继续存在,只是没有谁引用到它了.到时垃圾回收器会把它回收的.补充:
说下out 和ref的细小区别
ref 传进来的参数必须要先赋值.
像上面 的例子中如果这样写
int num;
ChangeInt(ref int num);
就会出错,必须先给num给个值1.
而且out传进来的参数可以不先赋值.
out num;
ChangeInt(out int num);是对的
另外还有个区别就是如果用out的时候ChangeInt函数中必须有某个地方给num赋值了,而用ref不一定需要在函数中给num赋值
其实这样做的目的很好理解.C#为了确保在任何情况下num必须有个值,不能为空.
因为用ref,在调用函数前必须保证参数有值,所以在函数中就不必要求它一定再赋值
而用out由于在调用函数前不用保证参数必须有值,所以在函数中必须保证给它个值
ChangeInt(ref int num)和ChangeInt(out int num)虽然不一样,但是不同共存,不能当作两个不同的函数
而ChangeInt(int num)和上面 的两个函数是完全不一样的,可以放到一起共存
这样的话调用的时候ref ,out这样的关键字不能省的.必须匹配
-
C#函数手册
2011-10-03 17:40:44C#函数手册 全面描述C#函数并加以实例说明,是程序必不可少的参考资料,函数非常全面,讲解也很好! -
Unity使用的C++动态库回调C#函数
2021-12-29 20:07:13Unity使用的C++动态库回调C#函数引言C++C#参考链接 引言 之前分享了一个文章:Unity显示C++动态库中的Log,其中使用到的主要能力就是,由C++动态库回调C#函数达到的。 这里我再对该功能进行专门的记录,并使用上面的...引言
之前分享了一个文章:Unity显示C++动态库中的Log,其中使用到的主要能力就是,由C++动态库回调C#函数达到的。
这里我再对该功能进行专门的记录,并使用上面的这个文章做例子。C++
首先,C++动态库中,先声明一个函数指针。
typedef void (*Log)(char* message, int iSize);
接着声明一下该指针类型的变量。
Log g_log;
如果需要将从C#传过来的函数地址全局保存,让其他的类都可以用这个回调函数,所以其他需要用到回调函数的ccp文件里,就需要再声明一次。
extern Log g_log;
然后就是导出一个接口,用来注册设置C#的函数地址。
头文件:#ifndef DLL_API #define DLL_API extern "C" #endif DLL_API void InitCSharpDelegate(void (*Log)(char* message, int iSize));
源文件:
DLL_API void InitCSharpDelegate(void (*Log)(char* message, int iSize)) { g_log = Log; }
这样,源文件的任何位置,当需要回调C#的函数时,只要调
g_log
就可以了。g_log(acLogStr, strlen(acLogStr));
C#
下面就是C#的代码,在C#中是由函数的委托来代替函数指针的。故代码如下。
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void LogDelegate(IntPtr message, int iSize); [DllImport("mac", CallingConvention = CallingConvention.Cdecl)] public static extern void InitCSharpDelegate(LogDelegate log); [MonoPInvokeCallback(typeof(LogDelegate))] public static void LogMessageFromCpp(IntPtr message, int iSize) { Debug.Log(Marshal.PtrToStringAnsi(message, iSize)); } public static void ShowLog() { InitCSharpDelegate(LogMessageFromCpp); }
现在,只需要在C#代码中调用
ShowLog
静态函数(设置注册回调)之后,C++动态库就能回调C#端的函数了。
完整的代码示例在文章Unity显示C++动态库中的Log中,但有些差别,可以一起对照查看。参考链接
-
C#函数实用手册
2008-01-31 19:17:37C#是Microsoft公司推出专门用于.NET的面向对象编程语言。本书涵盖了C#的核心类库,可以帮助程序员进行字符串处理、绘图、数学计算、数据库访问、网络应用等方面的工作,全面而系统地描述了使用C#语言编程常用的各种... -
C#函数的定义与调用
2017-03-29 12:52:30using System; using System.Collections.Generic;... *c#函数定义与调用 *函数(方法)作用: *功能分块处理,使用函数可以更好的管理代码。(例如:在多个地方出现重复功能的时候) *函数定 -
c# 函数注释方法(自动提示,并且函数说明,参数,返回换行显示)
2020-05-09 17:31:20//1、把<summary>标签包含<param>及<returns>; //2、在需要换行的地方填充<para /> /// <summary> /// 计算两个数的和<para /> /// <param name="a">...&l... -
C#函数的定义和使用
2018-10-21 08:04:36函数的定义,一般写在类(class) 下面。 using System; namespace ConsoleApp1 { class Program { static void Write()//函数的定义,void 表示无返回值,Write方法名 { //函数体也叫方法体,这里写... -
C#函数参数默认值及指定传参
2018-07-20 15:16:59编写函数通常会指定很多参数,但是调用时不一定每个参数都能用得上,使用参数默认值,可以避免在函数体中进一步...本文介绍C#函数参数默认值初始化,调用函数传参的顺序传参、指定参数传值,函数默认参数值的工作机制。 -
C++怎么调用C#函数
2018-02-10 17:27:23把C#编译成DLL或者Axtive控件,再由C调用 !比如使用C++调用C#的DLLSwfDotNet是C#编写的,作者的C#水平,真是令我佩服。这是个特别好的读写Swf文件的库。但是,我要用在C++项目中,怎么让C++调用C#的DLL呢。今天一... -
C++结构体/函数定义转换C#函数定义/结构体
2017-04-26 22:19:27把c++的结构体、数据类型、函数定义转换成对应的c#表达,很强大。 -
C#函数定义的语法格式 和 属性定义格式语法
2020-01-01 11:04:04函数定义的语法格式是 修饰词 返回值类型 函数名(参数列表) { 函数内容: (1).属性 (2).字段 (3)方法 (4)事件 (5)枚举 } (1).5种修饰词 (2).返回值类型 (3).自己起的函数名 ... -
C# 函数_out_输出参数
2019-02-12 22:55:49using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;...namespace _0705_函数_out_输出参数_ { class Program { //挑出字符串中的数字 ... -
C#:C#函数中数组作为形参传值
2018-02-09 01:09:12#params关键字:参考 public void ParamsArray(params int[] array){ foreach (int i in array){ Console.WriteLine("{0}", i); } } -
C# 函数_数组作为参数params
2019-02-12 22:57:06using System; using System.Collections.Generic; using System.Linq; using System.Text; using System....namespace _0707_函数_数组作为参数params_ { class Program { //参数数组演示,计算整数之和... -
C#函数的重载
2016-11-14 14:33:10◆函数名必须相同方能构成函数重载; ◆函数返回值类型:可以相同,也可以不同(注意:函数的返回类型不足以区分两个重载函数); ◆函数参数类型:必须不同; ◆函数参数个数:可以相同,可以不同 ◆函数参数顺序:... -
【C#函数式编程】C#中的函数式编程(一) —— =>表达式
2017-01-16 10:29:08一、函数式编程 函数式编程,简单来理解,就是把函数当成是组成一个功能模块最小的单位。... Labmda也称作匿名函数,在C#中我们通过一个简单的符号”=>”即可定义一个lamda表达式,下面分别针对不同的=>的使用方 -
C#函数中{get;set;}
2019-01-17 16:54:02在面向对象编程(OOP)中,...所以C#中就要用set和get方法来访问私有成员变量,它们相当于外界访问对象的一个通道,一个“接口”。先来看一段代码: class Employee { private string name; private byte age; ... -
C# javaScript函数的相互调用
2021-01-02 10:15:46如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问JavaScript的已有变量? 4.如何在C#中访问JavaScript函数? 问题1答案如下: javaScript函数中执行C#代码中的函数: 方法一:1、首先建立... -
c#函数库(比较常用)
2009-12-07 09:14:18C#常用的函数,不是太多,或者有帮助,或者大家都会,很适合初学者,内容不多,可以既得即用,很方便。