在c#中,我可以将类型对象的变量转换为类型T的变量,其中T在类型变量中定义?


当前回答

我永远不会理解为什么你需要50个声誉才能留下评论,但我不得不说@Curt的答案正是我想要的,希望是其他人。

在我的例子中,我有一个ActionFilterAttribute,我用来更新json补丁文档的值。我不知道补丁文档的T模型是什么,我必须将其序列化并反序列化为一个普通的JsonPatchDocument,修改它,然后因为我有类型,再次将其序列化并反序列化为类型。

Type originalType = //someType that gets passed in to my constructor.

var objectAsString = JsonConvert.SerializeObject(myObjectWithAGenericType);
var plainPatchDocument = JsonConvert.DeserializeObject<JsonPatchDocument>(objectAsString);

var plainPatchDocumentAsString= JsonConvert.SerializeObject(plainPatchDocument);
var modifiedObjectWithGenericType = JsonConvert.DeserializeObject(plainPatchDocumentAsString, originalType );

其他回答

当谈到转换为Enum类型时:

private static Enum GetEnum(Type type, int value)
    {
        if (type.IsEnum)
            if (Enum.IsDefined(type, value))
            {
                return (Enum)Enum.ToObject(type, value);
            }

        return null;
    }

你可以这样称呼它:

var enumValue = GetEnum(typeof(YourEnum), foo);

这对我来说是必要的情况下,获得几个枚举类型的描述属性值的int值:

public enum YourEnum
{
    [Description("Desc1")]
    Val1,
    [Description("Desc2")]
    Val2,
    Val3,
}

public static string GetDescriptionFromEnum(Enum value, bool inherit)
    {
        Type type = value.GetType();

        System.Reflection.MemberInfo[] memInfo = type.GetMember(value.ToString());

        if (memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), inherit);
            if (attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }

        return value.ToString();
    }

然后:

string description = GetDescriptionFromEnum(GetEnum(typeof(YourEnum), foo));
string description2 = GetDescriptionFromEnum(GetEnum(typeof(YourEnum2), foo2));
string description3 = GetDescriptionFromEnum(GetEnum(typeof(YourEnum3), foo3));

或者(更好的方法),这样的类型转换可以是这样的:

 private static T GetEnum<T>(int v) where T : struct, IConvertible
    {
        if (typeof(T).IsEnum)
            if (Enum.IsDefined(typeof(T), v))
            {
                return (T)Enum.ToObject(typeof(T), v);
            }

        throw new ArgumentException(string.Format("{0} is not a valid value of {1}", v, typeof(T).Name));
    }

你怎么能这么做?您需要一个类型为T的变量或字段,以便在转换后存储对象,但是如果您只在运行时知道T,您如何拥有这样的变量或字段呢?所以,这是不可能的。

Type type = GetSomeType();
Object @object = GetSomeObject();

??? xyz = @object.CastTo(type); // How would you declare the variable?

xyz.??? // What methods, properties, or fields are valid here?

为了简单起见,将装箱和解装箱放在一边,沿着继承层次结构进行强制转换时不涉及特定的运行时操作。这主要是编译时的事情。本质上,强制转换告诉编译器将变量的值视为另一种类型。

试镜之后你能做什么?你不知道它的类型,所以你不能对它调用任何方法。你不会有什么特别的事情可以做。具体来说,只有当你在编译时知道可能的类型,手动转换它并使用if语句分别处理每个case时,它才有用:

if (type == typeof(int)) {
    int x = (int)obj;
    DoSomethingWithInt(x);
} else if (type == typeof(string)) {
    string s = (string)obj;
    DoSomethingWithString(s);
} // ...

其他答案没有提到“动态”类型。因此,要再添加一个答案,您可以使用“动态”类型来存储结果对象,而不必使用静态类型强制转换转换后的对象。

dynamic changedObj = Convert.ChangeType(obj, typeVar);
changedObj.Method();

请记住,使用“动态”,编译器会绕过静态类型检查,如果你不小心,可能会引入运行时错误。

此外,还假定obj是typeVar类型的实例,或者可以转换为该类型。

当使用Zyphrax的答案时,没有找到任何东西来绕过“对象必须实现IConvertible”异常(实现接口除外)..我尝试了一些非常规的方法,但在我的情况下奏效了。

使用Newtonsoft。Json nuget包…

var castedObject = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(myObject), myType);