Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Generic Functions

Seeking some help on C# generics. I am working in Unity3D and am rolling a BiLerp function as Unity3D doesn't have one.

public Vector3 BiLerp(Vector2 _uv, Vector3 _00, Vector3 _01, Vector3 _10, Vector3 _11)
{
    return _00 * (1 - _uv.x) * (1 - _uv.y) +
           _10 * _uv.x * (1 - _uv.y) +
           _01 * _uv.y * (1 - _uv.x) +
           _11 * _uv.x * _uv.y;
}

However, I would like to make this function a little more robust.

  1. I would like to make it generic so that it takes in any type which can be multiplied by a float
  2. I am unsure as to whether or not I should make this static. I am assuming that as it does not use any member variable then yes. Should the class that this is stored in also be static, the class will just be for math helpers omitted by unity (Matrix2x2) etc.
  3. How does C# const work in this instance?
  4. In C++ I would pass the parameters by reference. I I correct in assuming that C# is already doing this? and that the ref keyword is some other dark magic tool?

If there is any other suggestions then please feel free. I have only been working in C# for 6 weeks now and could use any suggestions.

like image 849
Luke Turner Avatar asked Mar 23 '13 11:03

Luke Turner


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

Why is C named so?

Because a and b and c , so it's name is C. C came out of Ken Thompson's Unix project at AT&T. He originally wrote Unix in assembly language. He wrote a language in assembly called B that ran on Unix, and was a subset of an existing language called BCPL.


2 Answers

  1. Although it's possible to make this work by passing in a delegate that does the multiplication, it will be a lot slower. I actually think you'd be better off writing multiple overloads instead.

  2. Yes you should, and you should also put it into a static class. (IMHO!) I was going to suggest that you make it an extension method, but on reflection it has too many parameters to make it that useful.

  3. C# consts are similar to C++ consts, but the general consensus is that they should only be private (or possibly internal).

  4. Actually, Vector2 and Vector3 are structs so they are passed by value. If you want to pass them by reference, use the ref keyword:

    public Vector3 BiLerp(
        ref Vector2 _uv, ref Vector3 _00, ref Vector3 _01,
        ref Vector3 _10, ref Vector3 _11)`
    

However, there are only two reasons to do so (for structs):

  1. Because you want to change the original value being passed in.

  2. To speed it up by only passing a reference (i.e. pointer in C++ terms).

The first doesn't apply in your code, and the second seems pointless for such small structs (in fact, all structs should be small, so it almost never applies for well-designed structs).

like image 88
Matthew Watson Avatar answered Nov 10 '22 10:11

Matthew Watson


I would like to make it generic so that it takes in any type which can be multiplied by a float

Unfortunately C#'s generic type system does not support this kind of constraint. This is a fairly frequently requested feature that the C# team has considered, but it would require a lot of work in the underlying CLR type system. There is a chance that it will be implemented in the future, but I wouldn't hold my breath waiting for that day if I were you.

I am unsure as to whether or not I should make this static. I am assuming that as it does not use any member variable then yes.

Yes, make it static.

Should the class that this is stored in also be static, the class will just be for math helpers.

Yes.

How does C# const work in this instance?

C# const is different than C++ const; it is much simpler. In C# a const field or local is simply a name for a compile time constant number or string, end of story. (OK, you can also have a const of reference type but it must be null, so that's not that interesting.) There's none of this "here's a reference but you can't call any methods that mutate it" rules that you see in C#.

The best practice is to make all value types immutable in the first place, so C++-style const is not really necessary.

Marking a field "readonly" makes it so that it can only be changed in the constructor.

In C++ I would pass the parameters by reference. Am I correct in assuming that C# is already doing this?

No. Value types are passed by value.

the ref keyword is some other dark magic tool?

The ref keyword is just like C++ references: it makes one variable an alias for another. You would normally only use in C# for situations where you wanted to mutate a variable supplied by the caller. As I said before, C# does not have the C++ concept of a "const reference", but since value types in C# are supposed to be small, and therefore efficient to pass by value, you generally don't need the concept of "const reference" to say "I want to pass this by reference for performance but not actually mutate the variable".

like image 32
Eric Lippert Avatar answered Nov 10 '22 08:11

Eric Lippert