C# 实现C++中的 Cin以及Cout

本文介绍了如何在C#中通过操作符重载和unsafe特性模拟C++的Cout和cin输入输出模式,包括OStream和IStream类的实现,以及引用参数和指针的使用。作者强调这是一种简陋的实现方式,旨在帮助读者理解C#特殊语法的应用。
摘要由CSDN通过智能技术生成

今天在学C++的时候就突然想到C#能不能实现类似于C++的Cin和Cout的输入输出模式,于是就动手写了一下,发现想完全实现一样的功能是比较困难的,不过类似的功能还是可以的,以下是我的实现思路。

cout

操作符重载

众所周知,C++的Cin和Cout的基本使用方式如下。

int a, b;
std::cin >> a >> b;
std::cout << a + b << std::endl;

其中<<以及>>流式运算符,基本原理是利用了C++的操作符重载。因此,C#应该也可以通过操作符重载来实现这个功能。

cout实现

首先我们来实现比较简单的Cout输出。

class OStream
{
    public static readonly OStream Cout = new();
    public static string Endl => Environment.NewLine;

    public static OStream operator <<(OStream stream, object obj)
    {
        Console.Write(obj);
        return stream;
    }
}

使用方法如下,基本和C++一样。

_ = Cout << "Hello, World!" << endl; // Hello, World!

不过可能有细心的同学会发现,前面多了一个_ =面对一个不知道的问题,首先我们先问这是什么?然后再问为什么?

弃元

所以这是什么呢,首先这是一个赋值操作,等号左边为需要赋值的内容,右边是表达式,不过需要注意的是下划线 _ 并不是一个变量,而是C#的弃元,他的作用就是表示这个表达式的值我不需要,don't care。知道了这个作用之后,就可以解释这一行代码的作用了,这一行的作用就是输出“Hello World”,然后将这个表达式的值丢弃。

然后就是为什么需要这么做呢?显得非常莫名其妙,这其实应该算是C#的一个语法问题,C#的表达式不能单独作为一个语句,所以我们必须加上一个赋值操作,他才能独立存在。

cin

实现cout之后大家应该可以猜想到cin的实现方式了,就是借助操作符重载从输入流中读取数据之后再放入对应的对象中。

但是的话,这里就有一个问题,如何借助函数来对一个函数参数赋值,而函数参数通常只是一个副本,例如以下操作。

void Increase(int a)
{
    a++;
}

相信大家都能看出来这个函数并不能实现+1的功能,那需要怎么做呢?我们可以看看C++里面是如何实现的。 

void Increase(int &a)
{
    a++;
}

两份代码非常相似,但是C++的代码多了一个&符号代表引用,而正是通过引用,实现了这个功能,那C#呢,很幸运,C#也拥有类似的功能——引用参数

引用参数ref

该参数的用法简单来说就是C++的引用参数传递,是的参数传递时不是传递一个副本,而是传递本体。ref使用方法如下。

void Increase(ref int a)
{
    a++;
}

int a = 1;
Increase(ref a);
Console.WriteLine(a); // 2

​

大家需要注意的时候,在使用C#的引用参数时,我们需要显示的指出引用参数,也就是在参数前加上ref关键字。按理来说,我们有了以上的功能应该就可以实现cin的功能了,但是很不幸的是,C#的操作符重载不支持ref参数。所以我们还需要其他的办法。

既然引用无法使用,那么我们会想到C++的另一种输入方式,或者说是C的一种输入方式——scanf

int a;
scanf("%d", &a);

scanf则是使用了指针来实现这个功能,可能使用过C#的同学就会说了,C#没有指针啊,那这个方法也使用不了了,正常来说确实是这样子没错,但是C#有一个关键字unsafe。

不安全代码unsafe

那么这个unsafe关键字有什么用呢?它的作用就是允许你在C#中使用不安全代码,那么什么是不安全代码呢?简单来说就是带有指针的代码,没错,C#同样也是支持指针的,不过官方并不推荐我们使用,所以可能很多同学并不知道C#的指针,同样的,如果我们想要使用指针的话需要使用unsafe关键字来开启指针。以下就是unsafe的用法。

unsafe
{
    int a = 1;
    int *p = &a;
    *p = 2;
    Console.WriteLine(a); // 2
}

可以看到C#中的指针和C++中指针用法基本一致。

cin实现

基于unsafe,我可以使用指针来实现上述操作。以下是具体实现。

class IStream
{
    public static readonly IStream Cin = new();

    public static unsafe IStream operator >>(IStream stream, int* obj)
    {
        *obj = Convert.ToInt32(Console.ReadLine());
        return stream;
    }

    public static unsafe IStream operator >>(IStream stream, string* str)
    {
        *str = Console.ReadLine();
        return stream;
    }

    //...
}

在使用的时候我们也需要加上unsafe,使用方法。

unsafe
{
    int a = 0;
    _ = Cin >> &a;
}

总结

以上就是C#实现C++中的cin以及cout的办法。这只是一个非常简陋的实现方式,当然,应该也没人会有实现这个功能的需要,所以大家当个乐看就好,不过我觉得其中涉及的一些C#语法,大家可以去了解一下,因为虽然我们不一定需要C#版本的cin和cout,但是我们会需要这些特殊的语法来帮助我们更好的编写代码。最后,如果大家有什么问题和建议,欢迎在评论区提出!

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值