简体   繁体   English

C#如何使用Property

[英]c# how to use Property

I want to learn more about c#, and I've heard that you should use Private specifier and use get/set to make it public. 我想了解有关c#的更多信息,并且听说您应该使用Private说明符并使用get / set将其公开。

I got a small application that take textbox data and writes it to a file. 我有一个小应用程序,它可以接收文本框数据并将其写入文件。 And it encrypts the file. 并且它加密文件。

But I can't graps the concept about getters and setters. 但是我无法掌握有关获取器和设置器的概念。 Here is my one of my classes and Methods that writes to a file. 这是我写文件的类和方法之一。

     class MyClass
{
     public static bool WriteToFile(string text)
    {
        string FileName = "C:\\crypt\\crypt.txt";
        try
        {
            using (System.IO.StreamWriter WriteToFile = new System.IO.StreamWriter(FileName))
            {
                WriteToFile.Write(text);
                WriteToFile.Close();
            }
            return true;
        }
        catch
        {
            return false;
        }
    }

But instead i want to use a property. 但是我想使用一个属性。 How should i do it? 我该怎么办?

This is how i pass in the textbox-data from my main class. 这就是我从主类传递textbox-data的方式。

        public void button1_Click(object sender, EventArgs e)
    {
        MyClass c = new MyClass();
        if (MyClass.WriteToFile(textBox1.Text))
            MessageBox.Show("success, managed to write to the file");
        else
            MessageBox.Show("Error, Could not write to file. Please check....");

I've looked at various tutorials such as https://channel9.msdn.com/series/C-Fundamentals-for-Absolute-Beginners/15 and tutorials, but I really stuggling. 我看过各种教程,例如https://channel9.msdn.com/series/C-Fundamentals-for-Absolute-Beginners/15和教程,但我真的很努力。

WriteToFile is a method . WriteToFile是一种方法

Methods are methods, and properties are properties. 方法是方法,属性是属性。

Methods encapsulate behaviour, while properties encapsulate state . 方法封装行为,而属性封装state

WriteToFile should not be a property, because it does not encapsulate state. WriteToFile不应是属性,因为它不会封装状态。 In fact, it attempts to write into the file system. 实际上,它尝试写入文件系统。

An example of a property would be: 属性的示例为:

public class MyClass
{
      private bool _canWrite;

      /// Checks whether the file can be written into the file system
      public bool CanWrite 
      {
          get { return _canWrite; }
      }
}

From another class, you would call it like this: 在另一个类中,您可以这样称呼它:

if(myClass.CanWrite)
{
     // ...
}

Notice that CanWrite does not define any behaviour, it just defines a getter for the _canWrite field, this ensures that external classes don't get to see too much about your class. 请注意, CanWrite并未定义任何行为,它只是为_canWrite字段定义了一个吸气剂,这确保了外部类不会对您的类有太多了解。

Also notice that I define a getter only, this prevents others from setting your property. 还要注意,我仅定义了一个吸气剂,这会阻止其他人设置您的属性。

Okay so I think for you case you don't need a property, but if we assume you wan't to create some kind of wrapper class that handles all your writing to files you could do something along the lines of 好的,所以我认为对于您而言,您不需要属性,但是如果我们假设您不希望创建某种包装类来处理所有对文件的写入,则可以按照以下步骤进行操作

class AwesomeFileWriter
{
    private const string FileName = "C:\\crypt\\crypt.txt";
    private readonly string _text;

    public AwesomeFileWriter(string text)
    {
        _text = text;
    }

    public bool WriteToFile()
    {
        try
        {
            using (System.IO.StreamWriter WriteToFile = new System.IO.StreamWriter(FileName))
            {
                WriteToFile.Write(_text);
                WriteToFile.Close();
            }
            return true;
        }
        catch
        {
            return false;
        }
    }
}

There is not much to change to your design besides one little thing. 除了一件小事情,您的设计没有太多更改。 But first things first: 但首先要注意的是:

Could you place that code into a property? 您可以将该代码放入属性中吗? Sure. 当然。 Should you? 你应该? Not at all. 一点也不。 Your method WriteToFile is actually doing sth. 您的方法WriteToFile实际上正在做某事。 and thats what methods are for. 那就是什么方法。 Properties on the other hand are used for modifying/storing data. 另一方面,属性用于修改/存储数据。

Thats why property-names sound more like Names while method-names generally sound like Commands: 这就是为什么属性名称听起来更像名称,而方法名称通常听起来像命令的原因:

Example

public class Sample
{
    private string someText;

    // This Property Stores or modifies SomeText
    public string SomeText 
    {
        get { return this.someText; }        
        set { this.someText = value; }
    }

    // Method that does sth. (writes sometext to a given File)
    public void WriteSomeTextToFile(string File)
    {
         // ...
    }
}

Why properties/modifiers? 为什么选择属性/修饰符?

it is considered good pratice to encapsulate data within propeties like in the example above. 像上面的示例一样,将数据封装在属性内被认为是一种好习惯。 A small improvement could be the use of an AutoProperty like so: 小改进可能是使用AutoProperty,如下所示:

public string SomeText { get; set; }

which basically results in the same structure as the combination of an encapsulated field like in the first example. 基本上产生与第一个示例中的封装字段组合相同的结构。

Why? 为什么? : because this makes it easy to switch it out or to add logic to your get/set-operations. :,因为这样可以很容易地将其切换出去或为您的获取/设置操作添加逻辑。

For example, you could add validation: 例如,您可以添加验证:

public string SomeText 
{
        // ...
        set
        { 
            if (value.Length > 100)
                throw new Exception("The given text is to long!");

            this.someText = value; 
        }        
}

SideNote: Possible improvement to your class 注意:可能会改善您的课程

The only improvement I could think of is not to swallow the exception in your write method: 我唯一想到的改进就是不要在您的write方法中吞下异常:

public void WriteToFile()
{
    using (var fileWriter= new System.IO.StreamWriter(FileName))
    {
        fileWriter.Write(_text);
        fileWriter.Close();
    }
}

This is much cleaner and you would not have to "decision" cascades handling the same issue (your try / catch and if / else ) are practically doing the same. 这更加干净,您不必“决定”级联来处理相同的问题(您的try / catchif / else )实际上是在做相同的事情。

public void button1_Click(object sender, EventArgs e)
{
    try
    {
        var c = new MyClass();
        c.WriteToFile(textBox1.Text))
        MessageBox.Show("success, managed to write to the file");
    }
    catch(Exception e)
    {
        MessageBox.Show("Error, Could not write to file. " + e.Message);
    }
}

This way, you do not only have the same behaviour, but you also have more information than just the raw fact that your operation was unsuccessful ( false ) 这样,您不仅具有相同的行为,而且不仅拥有操作不成功的原始事实( false ),还拥有更多信息。

Without actually showing you the code I'll try and explain getters and setters so you can understand their concept. 在没有实际向您展示代码的情况下,我将尝试解释获取器和设置器,以便您了解其概念。

A property looks like a method to the internal class and field to an external class. 属性看起来像是内部类的方法,而字段是外部类的字段。

Eg You are able to perform logic in your property whereas when you call the property from a different class it behaves just like any other field. 例如,您可以在属性中执行逻辑,而当您从其他类调用属性时,其行为与任何其他字段一样。

GET: Used to retrieve and return a property. GET:用于检索和返回属性。 You are able to perform some complex logic before actually returning your property. 在实际返回属性之前,您可以执行一些复杂的逻辑。 You are able to safely expose private variables via the Get without compromising on writing. 您可以通过Get安全地公开私有变量,而不会影响编写。

SET: Used to set the value of a property that may be private, constant or public. SET:用于设置可以是私有,常量或公共属性的值。 You are able to have control over the setting of the variable. 您可以控制变量的设置。

Usually properties are used to keep values as attributes; 通常,属性用于将值保留为属性。 characteristics; 特性 settings. 设置。

Methods and functions you would think as actions. 您认为是行动的方法和功能。

eg as shown below: 例如如下所示:

public class MyClass{

/// <summary>
/// Keeps the file name
/// </summary>
public string FileName { get; set; }

/// <summary>
/// Action to write the file
/// </summary>
/// <returns>Returns true if the info. was wrote into the file.</returns>
public bool WriteToFileSucceed()
{        
    try
    {
        using (System.IO.StreamWriter WriteToFile = new System.IO.StreamWriter(FileName))
        {
            WriteToFile.Write(text);
            WriteToFile.Close();
        }
        return true;
    }
    catch
    {
        return false;
    }
}}

... ...

public void button1_Click(object sender, EventArgs e){

MyClass myClass = new MyClass();

myClass.FileName = @"C:\crypt\crypt.txt";

if(myClass.WriteToFileSucceed())
{
    MessageBox.Show("Success, managed to write to the file");
}
else
{   
    MessageBox.Show("Ops! Unable to write to the file.");
}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM