通用功能

时间:2015-02-12 19:26:58

标签: c# generics nullreferenceexception

我试图创建一个简单的通用函数:

    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
    }

奇怪的是typeof(T)行会返回此错误:

  

Object reference not set to an instance of an object.

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

另外如何返回构造的T类?

这就是我调用函数的方式:

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

这是User类:

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

2 个答案:

答案 0 :(得分:4)

您的代码存在的问题是您要查找字段,但T有自动属性。

因此,您需要致电:

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

此代码(剥离不必要的代码)有效:

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");
    }

}

答案 1 :(得分:1)

我担心你试图设置T的属性。但是T只是你传递给泛型方法的一种类型。你用new()约束它,所以据我所知T类型应该提供无参数构造函数。

假设你称之为GetPost<User>(request);

它应该返回设置了一些属性的用户。看看那个例子(用户类就像你写的那样)......

这是一个具有通用方法的类:

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();
            }
        }
    }
}

这是用法

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

执行变量“obj”之后是设置了密码字段的用户对象。

编辑:

我刚看到CommuSoft的帖子。我认为这是更好的解决方案,但我没有删除我的答案,也许有人会觉得它很有用。