2

I'm trying to create a simple generic function:

    public T GetPost<T>(HttpListenerRequest request) where T : new()
    {
        Stream body = request.InputStream;
        Encoding encoding = request.ContentEncoding;
        StreamReader reader = new StreamReader(body, encoding);

        string data = reader.ReadToEnd();
        body.Close();
        reader.Close();

        // NullRefferenceException on this line:
        typeof(T).GetField("Name").SetValue(null, "djasldj");


        return //yet to come
    }

Strangely the line with typeof(T) return this error:

Object reference not set to an instance of an object.

What is a NullReferenceException, and how do I fix it?

Also how can I return the constructed T class?

This is how I call the function:

 string data = GetPost<User>(ctx.Request);

And this is the User class:

public static string Name { get; set; }
public string Password { get; set; }
Community
  • 1
  • 1
Stijn Bernards
  • 1,091
  • 11
  • 29

2 Answers2

4

The problem with your code is that you look for a field, but your T has an automatic property.

You thus need to call:

typeof(T).GetProperty("Name").SetValue(null, "djasldj");

This code for instance (stripped unnecessary code) works:

class Foo {

    public static string Name { get; set; }
    public string Password { get; set; }

}

class Program
{
    static void Main()
    {
        Console.WriteLine(Foo.Name);
        GetPost<Foo>();
        Console.WriteLine(Foo.Name);
    }

    public static void GetPost<T>() where T : new() {
        typeof(T).GetProperty("Name").SetValue(null, "djasldj");
    }

}
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

I'm afraid you're trying to set property of T. But T is only a type you pass to the generic method. You've constrained it with new(), so as far as I know T type should provide parameterless constructor.

Let's say you call it GetPost<User>(request);

It should return user with some properties set. Take a look on that example (User class is as you wrote)...

This is a class with generic method:

namespace ConsoleApplication1
{
    class Class1
    {
        public T GetPost<T>(string s) where T : new()
        {
            if (typeof(T)== typeof(User))
            {
                var result = new User();
                result.Password = "some";
                return (T)(object)result;
            }
            else
            {
                throw new ArgumentException();
            }
        }
    }
}

And this is usage

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var c = new Class1();
            var obj = c.GetPost<User>("dsjkd");
        }
    }
}

After execution variable "obj" is User object with password field set.

EDIT:

I've just seen CommuSoft post. It's better solution I think, but I'm not deleting my answer, maybe someone will find it useful.

Arkadiusz Kałkus
  • 17,101
  • 19
  • 69
  • 108
  • But the compiler _does_ know the explicit type that T is at compile time. `GetPost` the type is `string`, which is a hard-coded value known at compile time. – ryanyuyu Feb 12 '15 at 19:39
  • In contrast to common belief, if one uses generics, the type **is** known at compile type. You can define a method with `` but for each use, that `T` is initialized. That's why Java's wildcards `?` are not supported. – Willem Van Onsem Feb 12 '15 at 19:42
  • Thank you. I was wrong. I'm sorry. – Arkadiusz Kałkus Feb 12 '15 at 20:02