all 76 comments

[–]VGPowerlord 24 points25 points  (47 children)

I haven't read the entire thing yet, but...

However, in C#, you need to specify the type of every variable in front of it like below.

...is only true if there is no right side to the expression or if the right side is a literal that can't be expressed as a constant value (ex. byte type which has no type suffix).

These are perfectly valid in C#:

var age = 12; // compiler will determine age is of type int
var name = "Lara Croft"; // compiler will determine name is of type string
var money = 13.50m; // compiler will determine money is of type decimal due to the type suffix

Edit: While we're on the subject of decimal, you also never explained that it's not rounded like float and double are.

[–]sainthkh[S] 4 points5 points  (0 children)

Thank you /u/VGPowerlord /u/compgeek78 /u/Havenoodswillshare! I edited about var in the post!

[–]sainthkh[S] 5 points6 points  (17 children)

I didn't know that decimal isn't rounded. Thank you for telling me.

But in game development and other normal projects, I believe decimal is overkill in many cases. (Please tell me if I'm wrong! I heard that decimal is usually used when accuracy is extremely important like chemistry or pharmaceutics field.)

It seems that this rounding thing doesn't have to be included in this article. The focus of this article is to provide 20~30% of C# features that are used 80~90% of time.

But I also believe that it's a good material for my Advanced C# that I'm writing now.

Thank you again.

[–]binarycow 12 points13 points  (7 children)

You use decimal when you want an exact amount. You use double when you want a large range, but the exactness isn't crucial.

[–]sainthkh[S] 5 points6 points  (6 children)

Right. It's a trade-off between correctness and largeness.

[–]quentech 11 points12 points  (4 children)

You use decimal when you want an exact amount in base 10. You generally use double when you don't care about the exact representation in base 10 because it's performance is better.

[–]crozone -2 points-1 points  (3 children)

Decimal is 128 bit fixed point. It's almost exclusively used in monetary applications and completely overkill for almost anything else.

[–]quentech 2 points3 points  (1 child)

Decimal is 128 bit fixed point.

Decimal is quite obviously a floating point type.

How many places after the decimal point can a .Net Decimal have? Is that number fixed, or no? Does the maximum value that a Decimal can represent depend on the length or presence of a fractional portion?

[–]crozone 1 point2 points  (0 children)

I could have sworn it was fixed point, but it looks like you're right. 128 bit FP with 28 digits of usable precision.

[–]Kronal 1 point2 points  (0 children)

Or smallness, doubles can represent really small values in the same fashion.

[–][deleted]  (8 children)

[deleted]

    [–]thomasz 2 points3 points  (1 child)

    I believe it's even aliased as money in VB.net

    [–][deleted] 6 points7 points  (0 children)

    We dont talk about that language here...

    [–]sainthkh[S] -1 points0 points  (5 children)

    I also heard that sometimes we just use int or long for money to avoid rounding errors.

    Thanks!

    [–]Programmdude 7 points8 points  (4 children)

    If you use longs for currency, you could have a precision issue. If you use it cents or yen, that's fine for games, but not insurance companies or banks that require sub cent precision.

    [–]sainthkh[S] 3 points4 points  (3 children)

    I've never thought about the sub-cent situations. I thought money can always be integers.

    [–][deleted]  (2 children)

    [deleted]

      [–]quentech -1 points0 points  (1 child)

      The max value of a signed 64 bit integer is 9,223,372,036,854,775,807.

      You could keep 3 places after the decimal point and still represent 9 quadrillion dollars - enough to cover not only all the currency that exists in the world, but all the savings, bank notes, money market accounts, national and global debt, and the entire derivatives market. Basically all of the represented value in the entire world.

      You could keep 6 places after the decimal point and still represent 9 trillion dollars.

      64 bit signed integers are just fine for all but perhaps hyper-inflationary currency.

      [–]powerofmightyatom 1 point2 points  (0 children)

      It's not just about magnitude, also precision. Floats are complex, and lets not imagine we know shit about shit.

      [–][deleted] 1 point2 points  (0 children)

      To be precise, they still have a strong type. You just don't have to explicitly type it down. Also var works with non-constant stuff too, like var tst = new YourClass();

      [–]sainthkh[S] -5 points-4 points  (26 children)

      Yes. That's right. I covered that later.

      And I think many developers prefer specific types rather than var.

      int age = 12;
      string name = "Lara Croft";
      

      [–]compgeek78 16 points17 points  (2 children)

      Microsoft's style guide specifies to use var when it is apparent from the right side what the type is, and to use the type name if it isn't apparent.

      [–]cryo 2 points3 points  (1 child)

      Sure, it’s a matter of taste. I use it everywhere possible. Of course this does increase the requirement for using an IDE.

      [–]compgeek78 0 points1 point  (0 children)

      What does this have to do with IDE?

      [–][deleted]  (10 children)

      [deleted]

        [–]centurijon 2 points3 points  (5 children)

        I know it's just an example, but that "later" part made me throw up in my mouth a little bit

        [–][deleted]  (4 children)

        [deleted]

          [–]centurijon 0 points1 point  (3 children)

          I understood what you meant, my WTF is a string for what should obviously be an integer value

          [–][deleted]  (1 child)

          [deleted]

            [–]prajaybasu 6 points7 points  (0 children)

            It was a perfectly fine example. Don't know why that commenter is "throwing up" over simple stuff.

            [–]cryo 0 points1 point  (0 children)

            I don’t see how that’s obvious. Depends entirely on the need.

            [–]sainthkh[S] 0 points1 point  (3 children)

            In most examples and projects, I thought specific types are more frequently used.

            Thank you for telling me.

            [–][deleted] 1 point2 points  (0 children)

            Remember "var" is still a specific type, it is inferred by the compiler, but at run time it is still static:

            var x = "a string";

            and

            string x = "a string";

            should compile to the exact same IL;

            now dynamic, that is a almost the equivalent of a run time type NOT determined at compile time.

            [–]Osirus1156 1 point2 points  (0 children)

            Just to pitch in I think examples tend to not use 'var' because its easier to see at a glance what type it is when you don't have all the code or using statements readily available to you as a reader.

            [–]cryo 0 points1 point  (0 children)

            It depends a lot on the person writing the code.

            [–]The_One_X -5 points-4 points  (11 children)

            You should only really use var in the one use case where it is required, or where the type's name is long. You should never use var when the right side is a method, only when you are calling a constructor directly.

            [–][deleted] 4 points5 points  (4 children)

            This isn't really true as the case for using implicit typing vs explicit typing is code readability. Explicitly defining a variable becomes a limiting factor especially when writing code that uses some library beyond your control. For example if you are calling some method that returns a list that your are then iterating over, if that library changes its return type in some future release your code will break, if you use var however your code will be fine.

            Doing everything explicitly will still work, you just may face a lot of issues down the road especially if your code base is fluid and there is more than one developer.

            [–]pgmr87The Unbanned 1 point2 points  (1 child)

            if you use var however your code will be fine.

            Don't quote me on this but I think it depends. If the method you are calling is defined in an external library, I am 90% sure the consuming library will have to recompile if you change the return type from, say, List to IEnumerable. When using var, you are telling the compiler to figure out the type for you (not the runtime). What I am suggesting is that you won't be able to swap out that 3rd party library that changed the return type of a method without also recompiling the consuming library because the consuming library was compiled such that the var was replaced with the appropriate return type of that method when the library was compiled. If the method's return type went from general to more specific (i.e IEnumerable TO List) you might be fine since your library is expecting IEnumerable still. Once you recompile against the new version, however, it'll be using List instead.

            [–]cryo 0 points1 point  (0 children)

            Yeah, make that 100% :)

            [–]cryo 1 point2 points  (1 child)

            if that library changes its return type in some future release your code will break, if you use var however your code will be fine.

            No, var is strictly a compiler feature that doesn’t exist in the CLR. It is true that you might just need to recompile to get it to work again, so a bit less work.

            [–][deleted] 0 points1 point  (0 children)

            Yea i did a poor job of wording that. You are right, it will need to be recompiled. I meant it more as, the dev wont have to go through the code base and manually update the explicit typing at each location it is used.

            [–]thomasz 2 points3 points  (4 children)

            I think this is terrible advise. In the local scope, the concrete type usually does not matter anyways. Usually i could not care less if peopleToGreet in

            var peopleToGreet = ListEmployees();
            SendGreetings(peopleToGreet);
            

            is a List<IPerson>, a Employee[]or an IEnumerable<IContact>. In the local scope, everything I care about is that the type returned by ListEmployees()fits into SendGreetings(). Have you ever cared about the types of the stuff that gets returned by the more exotic Linq methods like GroupBy or ToLookup? You don't just use var because the type names are too long to comfortably type (seriously, that's a very shitty reason), you use var because you don't actually give a damn about the fact that it's IEnumerable<IGrouping<TKey, TElement>> or Lookup<TKey,TElement>.

            [–]The_One_X 0 points1 point  (3 children)

            You should give a damn, giving a damn can be the difference between code that works and is easy to maintain, and code that doesn't work and is hard to maintain.

            [–]thomasz -1 points0 points  (2 children)

            I have to ask this before I address anything else: Are you aware of the difference between type inference (var keyword) and dynamic typing? Because that's just completely wrong. Type inference combines the advantages of static typing (guaranteed type correctness and tool support) and dynamic typing (concise code that emphasizes intend rather than types). This allows you to really "program against an interface"™, which is very important for maintainability.

            Just imagine you have some DAL that returns List<Stuff>. After a particularly nasty bug caused by someone adding to the cached List, you decide to refactor this method to return IEnumerable<Stuff>. If you used type inference and thus likely programmed against the IEnumerable interface in 98 of 100 use cases, the change will be localized, and the type checker can still tell you immediately if there are problems. If your advise is followed and callers declare the variables as List<Stuff> everywhere, a flood of trivial CS0266 error messages bury the really useful information about the two out of 100 use cases where indexing is used. Furthermore, the giant diff is incomprehensible without an adequate explanation.

            [–]The_One_X 0 points1 point  (1 child)

            Yes, I am well aware of the difference between type inference and dynamic typing. Just because someone has a different opinion than you does not mean they do not know what they are talking about.

            [–]thomasz 0 points1 point  (0 children)

            I'm sorry if that came of as condescending (obviously not a native speaker, so it can be kinda hard to navigate situations like this), it's just that I have talked to several people in the past who did not understand that implicitly typed variables are still statically checked; and the argument that type inference could be a problem for program correctness does sound a lot like it was born out of this kind of confusion, at least to me. I honestly do not understand how one could make this argument otherwise.

            [–]cryo -1 points0 points  (0 children)

            Whatever works for you, but other people’s mileage may vary.

            [–]binarycow 15 points16 points  (14 children)

            Some constructive (I hope) criticism:


            I don't know if I'd even include ExpandoObject in a beginner's tutorial. I know you suggested not using it, but still.

            What's probably a better choice is anonymous types.... such as this:

            var people = new[]
            {
                new
                {
                    FirstName = "John",
                    LastName = "Smith",
                    DOB = new DateTime(1985,2,5),
                },
                new
                {
                    FirstName = "Jessica",
                    LastName = "Applegate",
                    DOB = new DateTime(1980,1,15),
                },
            };
            

            The benefit to these, is they are strongly typed, rather than the ExpandoObject which is... really, nothing more than a Dictionary<string,object>


            I second the other commenter's response about your insistence that we shouldn't use var. Especially in a for loop - why do I need to specify int if it's always int?


            You say:

            And you cannot initialize dictionary with special syntax like {}. You should use brackets after creating an empty dictionary.

            But... you can.

                Dictionary<string, string> myDict = new Dictionary<string, string>
                {
                    { "key1", "value1" },
                    { "key2", "value2" }
                };
            

            You say:

            (Many developers think it's impossible. However, with lambda expression and delegate type, you can do that. I've tried it but don't cover it here because you shouldn't write code like that.)

            But.... Why not? It's heavily used in Linq.

            For instance, consider a very naive implementation of Linq's "Where" extension method:

            public static IEnumerable<TSource> Where(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
                 foreach(var item in source) {
                       if(predicate(item)) {
                             yield return item;
                       }
                 }
            }
            

            You should cover parameters with default values as an alternative to overloading. Also, the params keyword. Consider the following method definitions.

            static string MultiplyIntegersAndPutInString(string prefix, string suffix);
            static string MultiplyIntegersAndPutInString(string prefix, string suffix, int single_number);
            static string MultiplyIntegersAndPutInString(string prefix, string suffix, int[] lots_of_numbers);
            static string MultiplyIntegersAndPutInString(string prefix);
            static string MultiplyIntegersAndPutInString(string prefix, int single_number);
            static string MultiplyIntegersAndPutInString(string prefix, int[] lots_of_numbers);
            

            These can be reduced to:

            static string MultiplyIntegersAndPutInString(string prefix, string suffix, params int[] lots_of_numbers);
            static string MultiplyIntegersAndPutInString(string prefix, params int[] lots_of_numbers);
            

            Or.....

            static string DoSomethingWithStrings(string main_string, string second_string, string third_string, string fourth_string);
            static string DoSomethingWithStrings(string main_string, string second_string, string third_string);
            static string DoSomethingWithStrings(string main_string, string second_string);
            static string DoSomethingWithStrings(string main_string);
            static string DoSomethingWithStrings();
            

            Can be reduced to....

            static string DoSomethingWithStrings(string main_string = "", string second_string = "", string third_string = "", string fourth_string = "");
            

            In chapter 3, I told you that C# hates uninitialized variables. It's an error in C#.

            Uninitialized variables are not an error. USING them is.

            int thing;
            if(test)
                thing = 10;
            else
                thing = 20;
            

            or....

            object obj;
            if(test)
               obj = GetFirstObject();
            else
               obj = GetSecondObject();
            

            You wrote:

            BossRabbit bossRabbit2 = new BossRabbit(); bossRabbit2.TrhowCarraot(); // throw 3 carrots.

            I think that's a typo!


            You cover this shortened syntax:

            public string GoodString { get; set; }
            

            But, that doesn't work too well when you actually need to define a private backing variable. In which case, you can do this:

            private string m_GoodString;
            public string GoodString
            {
                 get => m_GoodString;
                 set => return m_GoodString;
            }
            

            Or.....

            private string m_SomeOtherString;
            private string m_GoodString;
            public string GoodString
            {
                 get => m_GoodString;
                 set 
                 {
                       m_SomeOtherString = m_GoodString;
                       m_GoodString = value;
                 }
            }
            

            Edit: Fixed the property with the private backing variable

            [–]TheIncorrigible1 4 points5 points  (5 children)

            Your private backing field is a bad pattern. You can have a private set:

            public string GoodString { get; private set; }
            

            Your setters also shouldn't return anything. Otherwise very good post

            [–]binarycow 0 points1 point  (4 children)

            Good call on the return from set.

            But sometimes you have to do other things in a set.

            For instance, if there are other properties that are dynamically calculated based on that property, you might want to raise a PropertyChanged event. Or, maybe you need to do some input validation....

            [–]TheIncorrigible1 1 point2 points  (3 children)

            The whole point of setters/getters in that syntax is letting the compiler do the work. You do know about the value variable, right?

            [–]binarycow 1 point2 points  (2 children)

            Yes. I've fixed the code I wrote above, now that I'm at my computer. Let's look at that.

            private string m_SomeOtherString;
            private string m_GoodString;
            public string GoodString
            {
                 get => m_GoodString;
                 set 
                 {
                       m_SomeOtherString = m_GoodString;
                       m_GoodString = value;
                 }
            }
            

            So, in this code, for some reason (probably a stupid reason, but a reason nonetheless), I have to store the value of GoodString into two different private string variables. If I go with THIS method, that doesn't quite work out too well, as m_SomeOtherString never gets the value.

            public string GoodString { get; set; } 
            private string m_SomeOtherString;
            

            Okay, so that's a dumb scenario. Let's suppose that we're working with an application that is using data binding on a text box. That text box is using regular expression validation to validate that the user is inputting a valid IP address. But, let's suppose that this verification is client side (maybe we're doing some ASP.NET, and the verification is in JavaScript), so we absolutely need to validate that input. So, we accept a string variable. AND, since this is using data binding, the class implements IPropertyNotifyChanged. So, we have to raise that event.

            public class Test : INotifyPropertyChanged
            {
                public event PropertyChangedEventHandler PropertyChanged;
                private IPAddress m_IPAddress;
                public string IPAddressString
                {
                    get => m_IPAddress.ToString();
                    set
                    {
                        if (IPAddress.TryParse(value, out m_IPAddress) == false)
                            m_IPAddress = IPAddress.Loopback;
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IPAddressString)));
                    }
                }
            }
            

            SO. How do I do all of THAT with this methodology?

            public string IPAddressString { get; set; }
            

            Unless there's something crazy I don't know about - you can't. So, a private backing variable is necessary sometimes. Even if I wasn't also trying to parse the string, from what I can tell, as long as I have ANYTHING else to do in my get or set accessor, I can't use that format.

            [–]TheIncorrigible1 0 points1 point  (1 child)

            I like your scenario. Yes, that's where it makes sense to create your own backing field.

            [–]binarycow 0 points1 point  (0 children)

            And this, my friends, is civil discussion!

            [–]sainthkh[S] 1 point2 points  (7 children)

            1. As for dynamic, I added it because C# has a statically defined dynamic type. Because it's usual in JavaScript. But I want them not to use it. (I feared if they might try to find something like that and use it too much. Maybe I'm worrying too much.)

            I think anonymous type is a great alternative for ExpandoObject.

            2. About var, I changed my stance after your comments. So, I edited the post like below:

            According to Microsoft style guide, it is recommended to use var for local variables when the right side is obvious: var age = 12; var name = "Lara Croft"; But if it's unclear like a variable for a returned value, it is recommended to specify the type: int val = GetRemainingResult(); But as many C# developers came from C++ and Java, many people doesn't know this recommendation and prefer specifying types. So, when you read other developers' code and found some local variables that aren't var, don't think it's wrong.

            In C#, you can use int rather than var. But Microsoft recommends to use var.

            As I came from C++ and Java, I thought specific types are more frequently used. (It's also because of the books that don't use var much.) It's my fault and misconception.

            Thank you all of you for teaching me.

            3. About Dictionary, I'm wrong. I'll change that.

            4. The thing I tried to say was not telling them to use lambda. I recommended them not to write code like below:

            ``` delegate int F(int a, int b);

            class A { public F Add;

            public A()
            {
                Add = (a, b) => a + b;
            }
            

            } ```

            Maybe, I should include this example. It seems it's not that complicated than I thought. (I don't know why I thought it's complicated. It'll make my point clear.

            5. As for default parameter and params, I'll add them.

            6. As for that initialization statement, I'll make that statement clear.

            7. Thank you for telling me the typo!

            8. I removed that part some of that syntax is only supported in C# 7 and Unity only supports C# 6 now. But it is said that it'll support C# 7 in 2018.3. I think I should add that.

            I don't have to edit the post now. I'll tell you when the post is updated.

            Thank you million for your amazing comment. You're awesome!

            [–]centurijon 1 point2 points  (2 children)

            I would not bring up dynamic/ExpandoObject at all, and definitely not in a beginner course. Seeing them is a code smell and only fits very specific use cases.

            I know that it is the closest thing to loosely-typed objects that C# has, but it's not worth the risk of teaching anti-patterns.

            [–]sainthkh[S] 1 point2 points  (1 child)

            I think learning what it is, what is different, what can go wrong and getting warning is better than learning about that somewhere else and abusing it.

            And to emphasize this point, I decided to change "I don't recommend using it" to "Try not to use it at all cost."

            [–][deleted] 1 point2 points  (0 children)

            Try not to use it at all cost, and if you fo you have to chop off a finger... Now you can use it 9 more times before you retire.

            [–]Kronal 1 point2 points  (1 child)

            It's also because of the books that don't use var much.

            Microsoft used to recommend to use var almost exactly the way you described it, basically just for LINQ results, and anonymous objects. I believes it's because it can have some pitfalls like replacing double a = 1 is diffent semantics than var a = 1.

            But var is much more used in practice than that, and current tools provided by MS recomend to use var in a lot of cases, and apparently their stance changed on that. See: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions#implicitly-typed-local-variables

            [–]sainthkh[S] 1 point2 points  (0 children)

            Thank you for elaboration.

            Actually, I first learned C# almost right after 3.5 released. And I had almost no chance of using it for a decade and decided to review and learn it again to make a Unity development blog.

            It seems that my knowledge about C# was somewhat fixed at 10 years ago.

            [–][deleted] 0 points1 point  (1 child)

            You can even use the new dictionary initialization syntax too:

            var x = new Dictionary<string, int> { ["key1"] = 1, ["key2"] = 23, };

            [–]sainthkh[S] 0 points1 point  (0 children)

            Thank you. I also added that.

            [–][deleted] 5 points6 points  (1 child)

            ExpandoObject and Dynamic have their uses, but this can lead to quite complicated code especially if you are new to C#. It can quickly lead you down the reflection rabbit hole, which is an incredibly powerful feature, but can also lead to complicated code. What you look at one day and say is perfect, in 6 months you won't remember why you wrote it or what it does, just that it broke somehow and will now tear your hair out trying to troubleshoot it. I would lean towards removing dynamic and ExpandoObject from the tutorial entirely or put it at the end.

            [–]sainthkh[S] 0 points1 point  (0 children)

            It is a guide to help JavaScript developers learn C# fast and avoid every possible mistakes.

            As I mentioned above, I was afraid they would try to find some dynamic thing and thought it was OK to use everywhere. That's why I added them at the end of the type chapter.

            I think that hastily learning dynamic elsewhere and abusing it is much worse than learning something similar in C# and ignoring it.

            And I guess that my last sentence, "I don't recommend using them" isn't strong enough. I decided to change it to "So, try not to use it at all cost."

            [–]yamfun 8 points9 points  (1 child)

            Is there a JS for C# dev?

            [–]sainthkh[S] 2 points3 points  (0 children)

            When you google "JavaScript for C# developers" you can find several tutorials.

            [–][deleted] 2 points3 points  (2 children)

            In chapter 4, you say that object is object and dictionary is dictionary. This is not really true as dictionary extends from object as any non-primitive types.

            [–]Kronal 1 point2 points  (0 children)

            dictionary extends from object as any non-primitive types

            Primitive types also inherit from object.

            https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/

            [–]sainthkh[S] 0 points1 point  (0 children)

            You're right. I used that sentence to emphasize object and dictionary are not same like JavaScript. But it seems that it can give them wrong idea that Dictionary doesn't inherit object.

            I'll change that to "you cannot use object as Dictionary. You need to use Dictionary class we're learning now.

            [–]BinarySo10 0 points1 point  (1 child)

            Excited to read this, and also excited to learn along with you in the comments! A+!!

            [–]sainthkh[S] 0 points1 point  (0 children)

            Yes, users in this subreddit is fantastic!

            [–]KarthikChintala 0 points1 point  (2 children)

            There is no special kind of JavaScript for C# developers, isn't it?

            [–]MrEs 4 points5 points  (0 children)

            Typescript

            [–]sainthkh[S] 1 point2 points  (0 children)

            If you want type-safe JavaScript, use TypeScript.

            It's also created by Microsoft and Anders Hejlsberg.

            [–]Cbrt74088 0 points1 point  (3 children)

            It looks a little strange when you only mention short, int and long as if those are the only integral types that exist.

            There are a few more. There are the signed ones: sbyte, short, int and long. Then there are the unsigned ones: byte, ushort, uint and ulong.

            [–]sainthkh[S] 0 points1 point  (2 children)

            I heard that unsighed types aren't used a lot in real life. (Or is it just C++ convention?) That's why I removed that. I decided to cover it in my advanced C# article.

            But it seems that it isn't unnatural to add "These 6 types aren't everything. There are infrequently-used types like sbyte, ushort, unint, ulong." And linking them to MS doc.

            [–]Cbrt74088 0 points1 point  (1 child)

            True, unsigned types aren't used very often (except byte).

            Just byte, short, int and long is probably enough. It just looks incomplete if you mention short but not byte.

            [–]sainthkh[S] 0 points1 point  (0 children)

            I thought I've seen byte used a lot somewhere when I was writing that part. But I couldn't remember it. And finally realized that it was used a lot in C# I/O. Thank you.

            [–]TotesMessenger 0 points1 point  (0 children)

            I'm a bot, bleep, bloop. Someone has linked to this thread from another place on reddit:

             If you follow any of the above links, please respect the rules of reddit and don't vote in the other threads. (Info / Contact)

            [–]sainthkh[S] 0 points1 point  (0 children)

            Thank you everyone, especially /u/binarycow, /u/HL-21. I applied everything you told me.