C# .NET:如何获得空对象的类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/254461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.NET : How do you get the Type of a null object?
提问by CodingWithSpike
I have a method with an out parameter that tries to do a type conversion. Basically:
我有一个带有 out 参数的方法试图进行类型转换。基本上:
public void GetParameterValue(out object destination)
{
object paramVal = "I want to return this. could be any type, not just string.";
destination = null; // default out param to null
destination = Convert.ChangeType(paramVal, destination.GetType());
}
The problem is that usually someone would call this like:
问题是通常有人会这样称呼它:
string output;
GetParameterValue(output);
This will fail because of:
这将失败,因为:
destination.GetType()
destination is null, so we can't call .GetType()
on it. We also can not call:
目的地为空,所以我们不能调用.GetType()
它。我们也不能调用:
typeof(destination)
because destination is a variable name not a type name.
因为目的地是变量名而不是类型名。
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
那么有没有办法获取设置为null的对象的类型?我认为必须有一种方法可以在不分配任何内容的情况下知道存储位置是什么类型。
Just to give a bit more info, I am trying to make a utility method that will grab the output parameters of an Oracle stored procedure. The issue is that DbParameter.Value
is of type object.
只是为了提供更多信息,我正在尝试创建一个实用程序方法来获取 Oracle 存储过程的输出参数。问题是它DbParameter.Value
是对象类型。
What would be ideal would be for the developers to do something like:
对于开发人员来说,理想的做法是:
string val = GetParameterValue("parameterName");
The notable thing is that there is no casting of types. In practice, you don't know the lparam of the "equals", so I went with:
值得注意的是,没有类型转换。实际上,你不知道“equals”的 lparam,所以我选择了:
string val;
GetParameterValue("parameterName", out val);
And figured within the method, I would know the destination type of the output variable. I guess that was a bad assumption. As an alternative, I also wrote the method:
在该方法中,我会知道输出变量的目标类型。我想这是一个糟糕的假设。作为替代,我还编写了该方法:
public T GetParameterValue<T>(string paramName)
So the developers can do:
所以开发者可以这样做:
string val = GetParameterValue<string>("parameterName");
I find the explicit "string" declaration to be repetitive, especially since in practice, the destination if probably an object property and the oracle data type could change (think ORM):
我发现显式的“字符串”声明是重复的,特别是因为在实践中,目标可能是对象属性和 oracle 数据类型可能会改变(想想 ORM):
MyObj.SomeProp = GetParameterValue<MyObj.SomeProp.GetType()>("parameterName");
But again, if MyObj.SomeProp is null, that .GetType()
call fails. The VM has to know the type of MyObj.SomeProp
, even when its null, right? or else how would it catch cast exceptions?
但同样,如果 MyObj.SomeProp 为空,则.GetType()
调用失败。VM 必须知道 的类型MyObj.SomeProp
,即使它为空,对吗?否则它将如何捕获强制转换异常?
To partially solve my own problem, I can do:
为了部分解决我自己的问题,我可以这样做:
MyObj.SomeProp = GetParameterValue<typeof(MyObj).GetField("SomeProp").GetType()>("parameterName");
The whole idea was to not have to explicitly use the Type in more than one place, so that if the data type changes, it only has to be changed in the destination object (MyObj.SomeProp
) and in the DB. There has to be a better way...
整个想法是不必在多个地方显式使用 Type,这样如果数据类型发生变化,只需在目标对象 ( MyObj.SomeProp
) 和 DB 中更改它。一定有更好的方法...
采纳答案by Marcus Griep
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
那么有没有办法获取设置为null的对象的类型?我认为必须有一种方法可以在不分配任何内容的情况下知道存储位置是什么类型。
Not necessarily. The best that you can say is that it is an object
. A null
reference does not point to any storage location, so there is no metadata from which it can make that determination.
不必要。你能说的最好的是它是一个object
. 甲null
参考不指向任意存储位置,所以没有元数据从其中可以作出这样的判定。
The best that you could do is change it to be more generic, as in:
您能做的最好的事情是将其更改为更通用,如下所示:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T
can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
的类型T
可以推断,因此您不需要显式地为该方法提供类型参数。
回答by Mark Cidade
In your example it would be null of type System.Object
.
在您的示例中,它将是 null 类型System.Object
。
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
你的例子甚至可以编译吗?我收到“无法从‘输出字符串’转换为‘输出对象’”错误。
回答by dub
The type of your destination variable is always System.Object
. You could just return
目标变量的类型始终是System.Object
. 你可以回去
Convert.ChangeType(paramVal, System.Object).
回答by Jelon
Currently you have no way of knowing what gets passed into the method. You can convert it into a generic method. Like this:
目前您无法知道传递给方法的内容。您可以将其转换为泛型方法。像这样:
public void GetParameterValue<T>(out T destination)
{
...
}
public void GetParameterValue<T>(out T destination)
{
...
}
回答by Ryan
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You mightconsider passing the Type as a parameter to GetParameterValue where you have more information, such as:
我认为当值为 null 时不可能获得类型。此外,由于您在 GetParameterValue 内部调用,因此您可以做的最好的事情(当值为 null 时)是获取“目标”参数的类型,即“对象”。您可以考虑将 Type 作为参数传递给您有更多信息的 GetParameterValue,例如:
public void GetParameterValue(Type sourceType, out object destination) { //... }
回答by Damian Powell
It's possible if you don't mind declaring your method as a generic. Try this.
如果您不介意将您的方法声明为泛型,这是可能的。尝试这个。
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
回答by Amy B
If there is no instance, there is no instance type.
如果没有实例,则没有实例类型。
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
您能做的最好的事情是使用引用的类型,这意味着如果您有对象引用(如问题中的方法),则引用类型为 object。
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
您可能不应该尝试将一种类型的空实例转换为另一种类型的空实例......
回答by James Curran
@Rally25s:
@Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
从你的消息(在答案中)不清楚那个问题是什么。如果声明为:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
正如您在上面写的那样,调用将起作用(您不需要指定类型)。我猜这对您不起作用,因为您不能将属性用作“输出”参数。解决方法是同时使用这两种方法:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
这将被称为这样:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
这是相当笨拙的,但不是提出的更糟糕的方法。
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
我在 C++ 中使用过但在 C# 中还没有尝试过的另一种方法是让 GetParameterValue() 一些你自己设计的对象,然后为它实现一些隐式转换运算符。
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
回答by JB King
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
在理论上,null 与 C 中的 void 指针并不完全相同,也就是说它保存了一个内存地址,仅此而已?如果是这样,那么它类似于数学中被零除的情况,其中结果未定义。
One could do the following for this line:
可以对这一行执行以下操作:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
只需删除第一个字符串,现在就没有重复了:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
不一定是您要查找的内容,尽管存在如何解释 null 的问题?
回答by JB King
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}