Reputation: 6261
I am getting an error that says:
'object' does not contain a definition for 'Title'
all the code is also on github
I have a ConsoleApplication1 that looks like this
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Movie m = new Movie();
var o = new { Title = "Ghostbusters", Rating = "PG" };
Console.WriteLine(m.PrintMovie(o));
}
}
}
and Movie.cs
public class Movie : DynamicObject
{
public string PrintMovie(dynamic o)
{
return string.Format("Title={0} Rating={1}", o.Title, o.Rating);
}
}
it works fine from the SAME project, but if I add ConsoleApplication2 with a reference to ConsoleApplication1 and add the Exact same code
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Movie m = new Movie();
var o = new { Title = "Ghostbusters", Rating = "PG" };
Console.WriteLine(m.PrintMovie(o));
}
}
}
I get an error:
'object' does not contain a definition for 'Title'**
even though it is in the dynamic object.
Here is a screen shot:
I am doing something like this and trying to call the movie function from a test project.
Upvotes: 114
Views: 75789
Reputation: 3437
Jahamal's answer doesn't say why you get the error. The reason is that the anonymous class is internal
to the assembly. Keyword dynamic
doesn't allow you to bypass member visibility.
The solution is to replace the anonymous class with named public class.
Here's another good example explaining the reason and another possible solution.
The reason the call to
data2.Person
fails is that the type information ofdata2
is not available at runtime. The reason it's not available is because anonymous types are not public. When the method is returning an instance of that anonymous type, it's returning aSystem.Object
which references an instance of an anonymous type - a type whose info isn't available to the main program. The dynamic runtime tries to find a property calledPerson
on the object, but can't resolve it from the type information it has. As such, it throws an exception. The call todata.Name
works fine sincePerson
is a public class, that information is available and can be easily resolved.
This can affect you in any of the following cases (if not more):
- You're returning a non-public, non-internal type using
System.Object
. 2. You're returning a non-public, non-internal derived type via a public base type and accessing a property in the derived type that's not in the base type. 3. You're returning anything wrapped inside an anonymous type from a different assembly.
Upvotes: 172
Reputation: 24
I am way late to the party, but here is a way I did it.
dynamic myObject = GetSomeObject();
//check if myObject is a special Object
(if myObject is specialObject)
{
string specialPropery = ((specialObject))myObject).SpecialProperty;
Console.WriteLine("The object is a special type. SpecialPropery: {specialPropery }");
}
else
{
Console.WriteLine("The object normal type.");
}
Upvotes: 0
Reputation: 1613
In my case I have a xUnit test project.
Where 'content' is a json string.
This code throws error:
dynamic parsed = JsonConvert.DeserializeObject<dynamic>(content);
This code works. Use ExpandoObject insted of dynamic like this:
dynamic parsed = JsonConvert.DeserializeObject<ExpandoObject>(content);
Upvotes: 5
Reputation: 1900
In my case I had a Unit Test project that I created on Visual Studio and a lot of cases where I needed to test methods on a data layer library. I didn't want to change all of them so I marked the test assembly as a friend by using:
[assembly:InternalsVisibleTo("MyDataLayerAssemblyName")]
And that solved it.
Example:
using System.Runtime.CompilerServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[assembly: InternalsVisibleTo( "MyDataLayerAssembly" )]
namespace MyUnitTestProject.DataTests
{
[TestClass]
public class ContactTests
{
...
References:
Upvotes: 39
Reputation: 1168
You need to use an ExpandoObject
dynamic o = new ExpandoObject();
o.Title = "Ghostbusters";
o.Rating = "PG";
Console.WriteLine(m.PrintMovie(o));
Upvotes: 103